ORY Project - heshed/aPaaS GitHub Wiki
Open Source Identity Infrastructure and Services ์ฌ์ฉ์ ๊ด๋ฆฌ, ๊ถํ ๋ฐ ์ญํ ๊ด๋ฆฌ, OAuth 2.0 ๋ฐ OpenID
- ORY Hydra
- OAuth 2.0 ๋ฐ OpenID Connect ๊ณต๊ธ์์ ๋๋ค.
- ORY Oathkeeper
- ์์ด๋ ๋ฐ ์ก์ธ์ค ํ๋ก์์ ๋๋ค.
- ORY Keto
- ์ก์ธ์ค ์ ์ด ์๋ฒ์ ๋๋ค.
- ORY Kratos
- ID ๊ด๋ฆฌ ์๋ฒ์ ๋๋ค.
- ๋ฐ์ดํฐ์ ์ฅ
- RDBMS(PostgreSQL, MySQL, SQLite)์ ์ ์ฅ
- CockroachDB ๋ฒ ํ
- ๋ฉ๋ชจ๋ฆฌ (dsn ์ memory ๋ก ์ง์ )
- https://k8s.ory.sh/helm/
- https://github.com/ory/k8s
- https://k8s.ory.sh/helm/hydra.html
- https://k8s.ory.sh/helm/oathkeeper.html
- https://k8s.ory.sh/helm/hydra-maester.html
- https://k8s.ory.sh/helm/oathkeeper-maester.html
helm repo add ory https://k8s.ory.sh/helm/charts
helm repo update
๊ฐ๋ฐ ์งํ์ค์ธ ๊ฒ์ผ๋ก ๋ณด์ด๊ณ , hydra, oathkeeper ์ ๋๋ง ๋ค์ด ์๋ ๋ฏ ํจ. ๋ฌธ์ ๋ถ์ค.
docker https://github.com/ory/examples/tree/master/full-stack
git clone https://github.com/ory/examples.git ory-example
cd ory-example
make start-full-stack
5๋ถ ์ ๋ ๋๊ธฐํ.. ๋ก๊ทธ ํ์ธ
docker logs hydra-bc_postgresd_1
docker logs hydra-bc_keto-migrate_1
docker logs hydra-bc_oathkeeper-migrate_1
docker logs hydra-bc_hydra-migrate_1
docker logs hydra-bc_services_1
์๋น์ค ํ์ธ
$ curl http://localhost:4445/clients
$ curl http://localhost:4456/rules
$ curl http://localhost:4466/engines/acp/ory/exact/policies
$ curl http://localhost:4466/engines/acp/ory/exact/roles
Open Policy Agent ์์ง์ ์ฌ์ฉ
- https://www.ory.sh/docs/keto/engines/acp-ory
- Access Control Policy DSL ๋ชจ๋ธ์ ์ฌ์ฉํจ.
- Role Based Access Control(RBAC)๋ ๋ฏธ๊ตฌํ๋ ์ํ(๊ฐ๋ฐ ๋ฆฌ์์ค๊ฐ ์๋ค๊ณ )
ACL ๊ตฌ์ฑ
-
subjects : "identity, user"
-
resources : ["member", "service", "collection" ]
-
actions : ["delete", "create", "read", "modify"]
- ๋ฆฌ์์ค ์ฌ์ฉ ํจํด(์์์ ๊ฐ ์ ํ ๊ฐ๋ฅ)
-
effect : "allow/deny"
- ๋ฆฌ์์ค์ ๋ํ ์ ๊ทผ์ ์ด ํ์ฉ์ฌ๋ถ (์์์ ๊ฐ ์ ํ ๊ฐ๋ฅ)
-
ory policies
[{
"subjects": ["role:owner"],
"resources": [
"resources:member",
"resources:service",
"resources:collection"
],
"actions": ["delete", "create", "read", "modify"],
"effect": "allow"
},
{
"subjects": ["role:admin"],
"resources": [
"resources:service",
"resources:collection"
],
"actions": ["delete", "create", "read", "modify"],
"effect": "allow"
},
{
"subjects": ["role:admin"],
"resources": [
"resources:member"
],
"actions": ["read"],
"effect": "allow"
},
{
"subjects": ["role:user"],
"resources": [
"resources:member",
"resources:service",
"resources:collection"
],
"actions": ["read"],
"effect": "allow"
}
]
RBAC ์ ์ ํํ ๋งค์นญ๋์ง ์๊ธฐ ๋๋ฌธ์ RBAC ๋ฃฐ๊ณผ ๋น์ทํ ํจ๊ณผ๋ฅผ ๋ด๋ ค๋ฉด https://www.ory.sh/docs/keto/sdk/api#get-an-ory-access-control-policy-role roles ์ role-member ๋ฐ์ดํฐ๋ก ๊ทธ๋ฃนํํ role ์ ์์ฑํ๊ณ , policy api ์ subjects์ role ๊ทธ๋ฃน์ ์ง์ ํด์ฃผ๋ ๋ฐฉ์์ผ๋ก ์งํํ๋ฉด ๋๊ฒ ๋ค.
member ๋ฐ์ดํฐ
- ํค member:kakao.com:heshed
[
{"id": "role:owner", "members": ["member:kakao.com:heshed", "member:kakao.com:heshed2"]},
{"id": "role:admin", "members": ["member:kakao.com:heshed", "member:kakao.com:heshed2"]}
{"id": "role:user", "members": ["member:kakao.com:heshed", "member:kakao.com:heshed2"]}
]
keto๋ string ๋งค์นญ, glob ํจํด๋งค์นญ URNs, ์ ๊ทํํ์, ์กฐ๊ฑด๋ฌธ๋ค, CIDR ์กฐ๊ฑด, Subject ์กฐ๊ฑด ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ์์ธํ ์ฌํญ์ https://www.ory.sh/docs/keto/engines/acp-ory ์์ ํ์ธํ ์ ์๋ค.
{
"subjects": ["users:*"],
"actions": ["get", "create"],
"resources": ["resources:articles:*", "resources:{accounts,profiles}:*"],
"effect": "allow"
}
- scope ์ถฉ๋์ ๋ฐฉ์งํ๊ธฐ ์ํด URN ๋ค์ด๋ฐ์ ์์ฑํ๋๋ก ํ๋ค.
Do not: my-resource
Do: myorg.com:my-resource
Do not: myorg.com:<subject-id>, myorg.com:<resource-id>, myorg.com:<action-id>
Do: myorg.com:subjects:<subject-id>, myorg.com:resources:<resource-id>, myorg.com:actions:<action-id>
Do: subjects:myorg.com:<subject-id>, resources:myorg.com:<resource-id>, actions:myorg.com:<action-id>
- Multi-Tenant Systems
Do: resources:myorg.com:tenants:<tenant-id>:<resource-id>
์ผ๋ถ ํ๊ฒฝ์๋ ํด๋น ์กฐ์ง์ ์ํ ์๋ธ์กฐ์ง ๋ฐ ํ๋ก์ ํธ๊ฐ ์๋ค. ์ด๋ฌํ ์ํฉ์์ ๋ค์ URN semantics๋ฅผ ์ฌ์ฉํ๋ค.
Do: resources:myorg.com:organizations:<organization-id>:projects:<project-id>:<resource-id>
-
incoming HTTP ๋ฆฌํ์คํธ์ ๋ํด์ ๊ถํ ์ฒดํฌ๋ฅผ ์ํํ๋ค.
-
ํด๋ผ์ฐ๋ ์ํคํ ์ฒ์์ ์ ์ฑ ์ํ์ง์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค. reverse proxy๋ก ๋จ๋ ์ผ๋ก ์คํํ๊ฑฐ๋, ๋ค๋ฅธ API Gateway ์ ํ๊ณผ ํ๋ฌ๊ทธ์ธ์ฒ๋ผ ๊ฒฐํฉํ์ฌ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค. (Kong, Nginx, Envoy, AWS API Gateway,...)
-
๊ตฌํํ ๋ฌธ์ ๋๋ฉ์ธ๊ณผ ์ค์ฝํ๋ Zero-Trust Network Architecture, Identity And Access Proxy (IAP)๋ผ๊ณ ๋ถ๋ฅธ๋ค. (https://www.beyondcorp.com/)
-
ORY Oathkeeper ๋ ORY Hydra, ORY Keto ์ ๋จ๋ ์ผ๋ก ๋์์ ์ํ๋ฉฐ, Oathkeeper's Access Control Decision API ๋ ๋ค๋ฅธ ์ ํ๋ค๊ณผ๋ ์ ๊ฒฐํฉํ์ฌ ๋์ํ๋ค.
- Ambassador via auth service
- Envoy via the External Authorization HTTP Filter
- AWS API Gateway via Custom Authorizers
- Nginx via Authentication Based on Subrequest Result
Example
๋ค์๊ณผ ๊ฐ์ ๋ฆฌํ์คํธ๊ฐ ๋ค์ด์จ๋ค๊ณ ๊ฐ์ ํ์๋
GET /my-service/whatever HTTP/1.1
Host: oathkeeper-proxy:4455
Authorization: bearer some-token
์๋์ rule ์ ๊ฐ์ง๊ณ ์๋ค๋ฉด
{
"id": "some-id",
"upstream": {
"url": "http://my-backend-service"
},
"match": {
"url": "http://oathkeeper-proxy:4455/my-service/whatever",
"methods": ["GET"]
},
"authenticators": [
{
"handler": "anonymous"
}
],
"authorizer": {
"handler": "allow"
},
"mutators": [
{
"handler": "noop"
}
]
}
ORY Oauthkeeper ๋ ๋ฆฌํ์คํธ๋ฅผ forward ํ ๊ฒ์ด๋ค.
GET /my-service/whatever HTTP/1.1
Host: my-backend-service:4455
Authorization: bearer some-token
๋ฆฌํ์คํธ๋ฅผ verify ํ๊ธฐ ์ํด decisoins
endpoint api ๋ฅผ ๋ณด๋ด ํ์ธํ ์ ์๋ค.
- GET /decisions/v1/api
- PUT /decisions/my/other/api
- DELETE /decisions/users?foo=?bar
Example
Assuming you are making the following request to ORY Oathkeeper's Access Control Decision API
GET /decision/my-service/whatever HTTP/1.1
Host: oathkeeper-api:4456
Authorization: bearer some-token
and you have the following rule defined (which allows this request)
{
"id": "some-id",
"match": {
"url": "http://oathkeeper-api:4456/my-service/whatever",
"methods": ["GET"]
},
"authenticators": [
{
"handler": "noop"
}
],
"authorizer": {
"handler": "allow"
},
"mutators": [
{
"handler": "noop"
}
]
}
then this endpoint will directly respond with HTTP Status Code 200:
HTTP/1.1 200 OK
Authorization: bearer some-token
If any other status code is returned, the request must not be allowed, for example:
HTTP/1.1 401 OK
Content-Length: 0
Connection: Closed
It is also possible to have this endpoint return other error responses such as the HTTP Status Found (HTTP Status Code 302), depending configured on the error handling. Use this feature only if your Reverse Proxy supports these type of responses.
Depending on the mutator defined by the access rule, the HTTP Response might contain additional or mutated HTTP Headers:
HTTP/1.1 200 OK
X-User-ID: john.doe
- Access Rule Matching
- Authentication
- Authorization
- Mutation
- Acess Rule ์ ์ธ์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ์ฌ ํฌ์๋ฉํ ์ ์๋ค.
-
X-User-ID: the-user-id
->Authorization: Bearer the.jwt.token