Slide 1

Slide 1 text

Open Policy Agent is Կ? 2018/09/06 @ken5scal

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

What I will talk 1. Why Policy Engine 2. What’s Policy Engine 3. Use-Case of Policy Engine

Slide 4

Slide 4 text

What I will talk 1. Why Policy Engine 2. What’s Policy Engine 3. Use-Case of Policy Engine

Slide 5

Slide 5 text

Policy: Rule to govern system behavior

Slide 6

Slide 6 text

What I will talk 1. Why Policy Engine 2. What’s Policy Engine 3. Use-Case of Policy Engine

Slide 7

Slide 7 text

RBAC is HARD

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

- Applying rules (operations) - Increasing Operation patterns - Sharing knowledge of Operation Main Concerns

Slide 13

Slide 13 text

Applying in High Level .BTUFS /PEF /PEF /PEF admin

Slide 14

Slide 14 text

kind: role version: v3 metadata: name: backend spec: allow: logins: - backend node_labels: '*': '*' rules: - resources: - session verbs: - list - read deny: node_labels: sre-only: true kind: role version: v3 metadata: name: frontend spec: allow: logins: - frontend node_labels: application: - “^front-web(\d+)$” service: - web rules: - resources: - session verbs: - list - read deny: {} kind: role version: v3 metadata: name: sre spec: allow: logins: - sre - admin node_labels: '*': '*' rules: - resources: - '*' verbs: - '*' kind: role version: v3 metadata: name: outsource spec: allow: logins: - outsource node_labels: env: - stg - dev deny: {} "MMPX"MM

Slide 15

Slide 15 text

kind: role version: v3 metadata: name: backend spec: allow: logins: - backend node_labels: '*': '*' rules: - resources: - session verbs: - list - read deny: node_labels: sre-only: true kind: role version: v3 metadata: name: frontend spec: allow: logins: - frontend node_labels: application: - “^front-web(\d+)$” service: - web rules: - resources: - session verbs: - list - read deny: {} kind: role version: v3 metadata: name: sre spec: allow: logins: - sre - admin node_labels: '*': '*' rules: - resources: - '*' verbs: - '*' kind: role version: v3 metadata: name: outsource spec: allow: logins: - outsource node_labels: env: - stg - dev deny: {} %FOZTPNFOPEFT

Slide 16

Slide 16 text

kind: role version: v3 metadata: name: backend spec: allow: logins: - backend node_labels: '*': '*' rules: - resources: - session verbs: - list - read deny: node_labels: sre-only: true kind: role version: v3 metadata: name: frontend spec: allow: logins: - frontend node_labels: application: - “^front-web(\d+)$” service: - web rules: - resources: - session verbs: - list - read deny: {} kind: role version: v3 metadata: name: sre spec: allow: logins: - sre - admin node_labels: '*': '*' rules: - resources: - '*' verbs: - '*' kind: role version: v3 metadata: name: outsource spec: allow: logins: - outsource node_labels: env: - stg - dev deny: {} "MMPXTPNFOPEF

Slide 17

Slide 17 text

kind: role version: v3 metadata: name: backend spec: allow: logins: - backend node_labels: '*': '*' rules: - resources: - session verbs: - list - read deny: node_labels: sre-only: true kind: role version: v3 metadata: name: frontend spec: allow: logins: - frontend node_labels: application: - “^front-web(\d+)$” service: - web rules: - resources: - session verbs: - list - read deny: {} kind: role version: v3 metadata: name: sre spec: allow: logins: - sre - admin node_labels: '*': '*' rules: - resources: - '*' verbs: - '*' kind: role version: v3 metadata: name: outsource spec: allow: logins: - outsource node_labels: env: - outsource env: - stg - dev deny: {} "MMPXTPNFFOW

Slide 18

Slide 18 text

Applying Configs to Multi-Env admin sytem B sytem C

Slide 19

Slide 19 text

Applying Configs to multi-systems admin

Slide 20

Slide 20 text

Applying to team (education)

Slide 21

Slide 21 text

ʊਓਓਓਓʊ ʼɹDeathɹʻ ʉY^Y^Y^Y^ʉ

Slide 22

Slide 22 text

What I will talk 1. Why Policy Engine 2. What’s Policy Engine 3. Use-Case of Policy Engine

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

Policy Engine - “It compares the request coming from the enforcement component against policy in order to determine whether the request is authorized or not” - “decouples the policy implementation from the business logic so that administrators can define policy without changing the application while still keeping up with the size, complexity, and dynamic nature of modern applications”

Slide 25

Slide 25 text

Policy Engine 4FSWJDF %FDJTJPO &OGPSDFNFOU-BZFS %FDPVQMF JO QSPDMFWFM 4FSWJDF &OGPSDFNFOU-BZFS 1PMJDZ&OHJOF %FDJTJPO-BZFS %PD 1PMJDZ query decision

Slide 26

Slide 26 text

1PMJDZ&OHJOF %FDJTJPO-BZFS %BUB %PDVNFOU 1PMJDZ 3VMF How OPA works

Slide 27

Slide 27 text

Data - Base Document 1PMJDZ&OHJOF %FDJTJPO-BZFS %BUB %PDVNFOU 1PMJDZ 3VMF - In memory - can store in Disk - Represented in JSON - Restful HTTP API - Data API

Slide 28

Slide 28 text

curl -X PUT --data-binary @data.json localhost:8181/v1/data/servers { "servers": [ {"id": "s1", "name": "app", "protocols": ["https", "ssh"], "ports": ["p1", "p3"]}, {"id": "s2", "name": "db", "protocols": ["mysql"], "ports": [“p1”, "p2"]}, {"id": "s3", "name": "cache", "protocols": ["memcache"], "ports": [“p1”, “p2"]}, {"id": "s4", "name": "dev", "protocols": ["http"], "ports": ["p1", "p3"]} ], "networks": [ {"id": "n1", "public": false}, {"id": "n2", "public": false}, {"id": "n3", "public": true} ], "ports": [ {"id": "ssh", "networks": ["n1"]}, {"id": “db", "networks": ["n2"]}, {"id": "web", "networks": ["n3"]} ] }

Slide 29

Slide 29 text

PUT https://example.com/v1/data/servers HTTP/1.1 Content-Type: application/json-patch+json { "servers": [ {"id": "s1", "name": "app", "protocols": ["https", "ssh"], "ports": ["mgt", “web"]}, {"id": "s2", "name": "db", "protocols": ["mysql"], "ports": [“mgt”, "db"]}, {"id": "s3", "name": "cache", "protocols": ["memcache"], "ports": [“mgt”, “db"]}, {"id": "s4", "name": "dev", "protocols": ["http"], "ports": ["mgt", "web"]} ], "networks": [ {"id": "n1", "public": false}, {"id": "n2", "public": false}, {"id": "n3", "public": true} ], "ports": [ {"id": "mgt", "networks": ["n1"]}, {"id": “db", "networks": ["n2"]}, {"id": "web", "networks": ["n3"]} ] }

Slide 30

Slide 30 text

Policy (Rule) 1PMJDZ&OHJOF %FDJTJPO-BZFS %BUB %PDVNFOU 1PMJDZ 3VMF - Written in Rego - purpose-built - declarative - Represented in JSON - Restful HTTP API - Policy API

Slide 31

Slide 31 text

curl -X PUT --data-binary @server-rule.rego localhost:8181/v1/policies/servers package opa.example import data.servers import data.networks import data.ports public_servers[s] { s = servers[_] s.ports[_] = ports[i].id ports[i].networks[_] = networks[j].id networks[j].public = true } violations[server] { server = servers[_] server.protocols[_] = "http" public_servers[server] = true }

Slide 32

Slide 32 text

package opa.example import data.servers import data.networks import data.ports public_servers[s] { s = servers[_] s.ports[_] = ports[i].id ports[i].networks[_] = networks[j].id networks[j].public = true } violations[server] { server = servers[_] server.protocols[_] = "http" public_servers[server] = true }

Slide 33

Slide 33 text

package opa.example import data.servers import data.networks import data.ports public_servers[s] { s = servers[_] s.ports[_] = ports[i].id ports[i].networks[_] = networks[j].id networks[j].public = true } violations[s] { s = servers[_] s.protocols[_] = "http" public_servers[s] }

Slide 34

Slide 34 text

curl -X GET localhost:8181/v1/data/opa/example/violations [ { "id": "s4", "name": "dev", "ports": [ "p1", "p2" ], "protocols": [ "http" ] } ]

Slide 35

Slide 35 text

How OPA is deployed 4FSWJDF import ( “github.com/open-policy-agent/* ) EBFNPOTFSWJDF EBFNPO DPOUBJOFSTFSWJDF DPOUBJOFS

Slide 36

Slide 36 text

- Unified - Declarative - Context-Aware Feature

Slide 37

Slide 37 text

- Unified - Declarative - Context-Aware Feature

Slide 38

Slide 38 text

- Unified - Declarative - Context-Aware Feature

Slide 39

Slide 39 text

- Unified - Declarative - Context-Aware Feature

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

What I will talk 1. Why Policy Engine 2. What’s Policy Engine 3. Use-Case of Policy Engine

Slide 42

Slide 42 text

- Docker - Web-server - Terraform Use-cases

Slide 43

Slide 43 text

[ { "labels": { "app": "my-example-app", "id": "1780d507-aea2-45cc-ae50-fa153c8e4a5a" }, "decision_id": "4ca636c1-55e4-417a-b1d8-4aceb67960d1", "revision": "W3sibCI6InN5cy9jYXRhbG9nIiwicyI6NDA3MX1d", "path": "http/example/authz/allow", "input": { "method": "GET", "path": "/salary/bob" }, "result": "true", "requested_by": "[::1]:59943", "timestamp": "2018-01-01T00:00:00.000000Z" } ]

Slide 44

Slide 44 text

{ "labels": { "app": "my-example-app", "id": "1780d507-aea2-45cc-ae50-fa153c8e4a5a" }, "bundle": { "name": "http/example/authz", "active_revision": "TODO", "last_successful_download": "2018-01-01T00:00:00.000Z", "last_successful_activation": "2018-01-01T00:00:00.000Z" } }

Slide 45

Slide 45 text

- Payment Service - Everyone can see their own payment - Manager can see her/his member’s payment - HR Dep can see all employee’s payment Use-Case: Web-Service

Slide 46

Slide 46 text

version: '2' services: api_server: image: openpolicyagent/demo-restful-api:0.2 ports: - 5000:5000 environment: - OPA_ADDR=http://opa:8181 - POLICY_PATH=/v1/data/httpapi/authz opa: image: openpolicyagent/opa:0.9.0 ports: - 8181:8181 command: - "run" - "--server" - "--log-level=debug" IUUQTXXXPQFOQPMJDZBHFOUPSHEPDTIUUQBQJBVUIPSJ[BUJPOIUNM

Slide 47

Slide 47 text

# Grab basic information. We assume user is passed on a form. http_api_user = request.form['user'] orig_path_list = request.path.split("/") # Remove empty entries from list that are a result of the split # Example: "/finance/salary/" will become ["", "finance", "salary", ""] http_api_path_list = [x for x request.path.split("/") if x] input_dict = { # create input to hand to OPA "input": { "user": request.form['user'], "path": [x for x request.path.split("/") if x], "method": request.method } } # ask OPA for a policy decision # (in reality OPA URL would be constructed from environment) rsp = requests.post("http://127.0.0.1:8181/v1/data/httpapi/authz", data=json.dumps(input_dict)) if rsp.json()["allow"]: # HTTP API allowed else:

Slide 48

Slide 48 text

version: '2' services: api_server: image: openpolicyagent/demo-restful-api:0.2 ports: - 5000:5000 environment: - OPA_ADDR=http://opa:8181 - POLICY_PATH=/v1/data/httpapi/authz opa: image: openpolicyagent/opa:0.9.0 ports: - 8181:8181 command: - "run" - "--server" - "--log-level=debug" IUUQTXXXPQFOQPMJDZBHFOUPSHEPDTIUUQBQJBVUIPSJ[BUJPOIUNM

Slide 49

Slide 49 text

package httpapi.authz # HTTP API request import input as http_api default allow = false # Allow users to get their own salaries. allow { http_api.method = "GET" http_api.path = ["finance", "salary", username] username = http_api.user } # Allow managers to get their member' salaries. # bob is alice's manager, and betty is charlie's. members = {"alice": [], "charlie": [], "bob": ["alice"], "betty": [“charlie"]} allow { http_api.method = "GET" http_api.path = ["finance", "salary", username] members[http_api.user][_] = username } # Allow HR members to get anyone's salary. hr = [ “david" ] allow { http_api.method = "GET" http_api.path = ["finance", "salary", _] hr[_] = http_api.user } DVSMVTFSBMJDFQBTTXPSEMPDBMIPTUpOBODFTBMBSZBMJDF 4VDDFTTVTFSBMJDFJTBVUIPSJ[FE

Slide 50

Slide 50 text

package httpapi.authz # HTTP API request import input as http_api default allow = false # Allow users to get their own salaries. allow { http_api.method = "GET" http_api.path = ["finance", "salary", username] username = http_api.user } # Allow managers to get their member' salaries. # bob is alice's manager, and betty is charlie's. members = {"alice": [], "charlie": [], "bob": ["alice"], "betty": [“charlie"]} allow { http_api.method = "GET" http_api.path = ["finance", "salary", username] members[http_api.user][_] = username } # Allow HR members to get anyone's salary. hr = [ “david" ] allow { http_api.method = "GET" http_api.path = ["finance", "salary", _] hr[_] = http_api.user } DVSMVTFSCPCQBTTXPSEMPDBMIPTUpOBODFTBMBSZBMJDF 4VDDFTTVTFSCPCJTBVUIPSJ[FE

Slide 51

Slide 51 text

package httpapi.authz # HTTP API request import input as http_api default allow = false # Allow users to get their own salaries. allow { http_api.method = "GET" http_api.path = ["finance", "salary", username] username = http_api.user } # Allow managers to get their member' salaries. # bob is alice's manager, and betty is charlie's. members = {"alice": [], "charlie": [], "bob": ["alice"], "betty": [“charlie"]} allow { http_api.method = "GET" http_api.path = ["finance", "salary", username] members[http_api.user][_] = username } # Allow HR members to get anyone's salary. hr = [ “david" ] allow { http_api.method = "GET" http_api.path = ["finance", "salary", _] hr[_] = http_api.user } DVSMVTFSEBWJEQBTTXPSEMPDBMIPTUpOBODFTBMBSZBMJDF 4VDDFTTVTFSEBWJEJTBVUIPSJ[FE DVSMVTFSEBWJEQBTTXPSEMPDBMIPTUpOBODFTBMBSZCPC 4VDDFTTVTFSEBWJEJTBVUIPSJ[FE

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

- Unauthorize user from executing docker commands - Docker for MacͩͱόάΔ Use-Case: Docker Authz

Slide 54

Slide 54 text

# OPA-docker-auth plugin % docker run -d --restart=always -v $PWD/policies:/policies -v /run/docker/plugins:/run/ docker/plugins openpolicyagent/opa-docker-authz:0.2 -policy-file /policies/example.reg # Inside the rule (Deny any request % cat policies/example.rego package docker.authz default allow = false # Run Docker Daemon w/ opa-docker-auth plugin as Access Authorization plugin % /usr/bin/dockerd -H fd:// —authorization-plugin=opa-docker-authz # Watch % docker ps Error response from daemon: authorization denied by plugin opa-docker-authz: request rejected by administrative policy

Slide 55

Slide 55 text

# OPA-docker-auth plugin % docker run -d --restart=always -v $PWD/policies:/policies -v /run/docker/plugins:/run/docker/plugins openpolicyagent/opa-docker-authz:0.2 -policy-file /policies/example.reg # Inside the rule (Deny any request % cat policies/example.rego package docker.authz default allow = false # Run Docker Daemon w/ opa-docker-auth plugin as Access Authorization plugin % /usr/bin/dockerd -H fd:// —authorization-plugin=opa-docker-authz # Watch % docker ps Error response from daemon: authorization denied by plugin opa-docker-authz: request rejected by administrative policy

Slide 56

Slide 56 text

# OPA-docker-auth plugin % docker run -d --restart=always -v $PWD/policies:/policies -v /run/docker/plugins:/run/docker/plugins openpolicyagent/opa-docker-authz:0.2 -policy-file /policies/example.reg # Inside the rule (Deny any request % cat policies/example.rego package docker.authz default allow = false # Run Docker Daemon w/ opa-docker-auth plugin as Access Authorization plugin % /usr/bin/dockerd -H fd:// —authorization-plugin=opa-docker-authz # Watch % docker ps Error response from daemon: authorization denied by plugin opa-docker-authz: request rejected by administrative policy

Slide 57

Slide 57 text

# OPA-docker-auth plugin % docker run -d --restart=always -v $PWD/policies:/policies -v /run/docker/plugins:/run/docker/plugins openpolicyagent/opa-docker-authz:0.2 -policy-file /policies/example.reg # Inside the rule (Deny any request % cat policies/example.rego package docker.authz default allow = false # Run Docker Daemon w/ opa-docker-auth plugin as Access Authorization plugin % /usr/bin/dockerd -H fd:// —authorization-plugin=opa-docker-authz # Watch % docker ps Error response from daemon: authorization denied by plugin opa-docker-authz: request rejected by administrative policy

Slide 58

Slide 58 text

# OPA-docker-auth plugin % docker run -d --restart=always -v $PWD/policies:/policies -v /run/docker/plugins:/run/docker/plugins openpolicyagent/opa-docker-authz:0.2 -policy-file /policies/example.reg # Inside the rule (Deny any request % cat policies/example.rego package docker.authz default allow = false # Run Docker Daemon w/ opa-docker-auth plugin as Access Authorization plugin % /usr/bin/dockerd -H fd:// —authorization-plugin=opa-docker-authz # Watch % docker ps Error response from daemon: authorization denied by plugin opa-docker-authz: request rejected by administrative policy

Slide 59

Slide 59 text

# OPA-docker-auth plugin % docker run -d --restart=always -v $PWD/policies:/policies -v /run/docker/plugins:/run/docker/plugins openpolicyagent/opa-docker-authz:0.2 -policy-file /policies/example.reg # Inside the rule (Deny any request % cat policies/example.rego package docker.authz default allow = false # Run Docker Daemon w/ opa-docker-auth plugin as Access Authorization plugin % /usr/bin/dockerd -H fd:// —authorization-plugin=opa-docker-authz # Watch % docker ps Error response from daemon: authorization denied by plugin opa-docker-authz: request rejected by administrative policy

Slide 60

Slide 60 text

% cat policies/example.rego package docker.authz default allow = false # allow if the user is granted read/write access. allow { user_id = input.Headers["Authz-User"] user = users[user_id] not user.readOnly } # users defines permissions for the user. In this case, we define a single # attribute 'readOnly' that controls the kinds of commands the user can run. users = { "alice": {"readOnly": false}, }

Slide 61

Slide 61 text

% cat ~/.docker/config.json { "HttpHeaders": { "Authz-User": "alice" } }

Slide 62

Slide 62 text

% docker ps % docker logs 2018/08/12 13:08:39 Querying OPA policy data.docker.authz.allow. Input: { "AuthMethod": "", "Body": null, "Headers": { "User-Agent": "Go-http-client/1.1" }, "Method": "GET", "Path": "/containers/ 8690a3302bb73d29c7cd182b91058e7549e0fbb10f0f025c604d8f793f63bb aa/json", "User": “alice" } 2018/08/12 13:08:39 Returning OPA policy decision: true

Slide 63

Slide 63 text

- SSH - Terraform Other Use Cases

Slide 64

Slide 64 text

- Plugins - https://github.com/open-policy-agent/opa-istio- plugin - https://github.com/open-policy-agent/opa-kube- scheduler Other Use Cases

Slide 65

Slide 65 text

Conclusion

Slide 66

Slide 66 text

- Why Policy Engine - RBACΛ࢝Ίͱͨ͠ϧʔϧద༻ͷਏΈ - What’s Policy Engine - Policy Engineొ৔ - Unified, Declartive & Context-AwareͳOPAొ৔ - Use Case of Policy Engine - HTTP API, Docker - ୺຤ϕʔεͷೝՄʹܨ͛ΒΕΔͱ͍Ζ͍ΖḿΓͦ͏ ·ͱΊ

Slide 67

Slide 67 text

No content