Skip to content

Latest commit

 

History

History
783 lines (679 loc) · 24.6 KB

keti-demo.org

File metadata and controls

783 lines (679 loc) · 24.6 KB

Keti Demo

Note: Keti was earlier called ACS. This repository still has references to artifacts with that name and can be treated as synonymous to Keti.

Overview

This document provides basic information intended to get users started with Eclipse Keti. We will explore two use cases:

  • Access control based on group membership.
  • Access control based on dynamic roles. The roles are dynamic in the sense that a user’s role will depend on the resources they are attempting to access. E.g. the user tom@ge.com is an analyst only when accessing resources that belong to a specific site.

Technology Stack

This project makes heavy use of various Spring frameworks including:

The attribute store is a graph database built on:

Persistence storage includes:

architecture.png

Setting up UAA

Getting and running UAA

  • Clone UAA next to Keti project
git clone https://github.com/cloudfoundry/uaa ../uaa
  • Copy UAA config file. Keti requires a UAA configuration that uses asymmetric signing of tokens instead of the default symmetric singing.
cp acs-integration-tests/uaa/config/uaa.yml ../uaa/uaa/src/main/resources/uaa.yml
  • Start UAA
cd ../uaa
./gradlew run --info

Use OAuth 2.0 client credentials to get admin token

We’ll use the UAA admin client to further configure UAA for our demo. You can get an admin access token by using the OAuth 2.0 client credentials grant type with the client id and secret submitted using HTTP basic auth.

POST http://localhost:8080/uaa/oauth/token
Authorization: Basic YWRtaW46YWRtaW5zZWNyZXQ=

grant_type=client_credentials
{
  "jti": "ea09297877b54225b01c5a739d48b850",
  "scope": "clients.read clients.secret clients.write uaa.admin clients.admin scim.write scim.read",
  "expires_in": 43199,
  "token_type": "bearer",
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiJlYTA5Mjk3ODc3YjU0MjI1YjAxYzVhNzM5ZDQ4Yjg1MCIsInN1YiI6ImFkbWluIiwiYXV0aG9yaXRpZXMiOlsiY2xpZW50cy5yZWFkIiwiY2xpZW50cy5zZWNyZXQiLCJjbGllbnRzLndyaXRlIiwidWFhLmFkbWluIiwiY2xpZW50cy5hZG1pbiIsInNjaW0ud3JpdGUiLCJzY2ltLnJlYWQiXSwic2NvcGUiOlsiY2xpZW50cy5yZWFkIiwiY2xpZW50cy5zZWNyZXQiLCJjbGllbnRzLndyaXRlIiwidWFhLmFkbWluIiwiY2xpZW50cy5hZG1pbiIsInNjaW0ud3JpdGUiLCJzY2ltLnJlYWQiXSwiY2xpZW50X2lkIjoiYWRtaW4iLCJjaWQiOiJhZG1pbiIsImF6cCI6ImFkbWluIiwiZ3JhbnRfdHlwZSI6ImNsaWVudF9jcmVkZW50aWFscyIsInJldl9zaWciOiI5N2M1MDBiYiIsImlhdCI6MTQ2OTU2MzU0NiwiZXhwIjoxNDY5NjA2NzQ2LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvdWFhL29hdXRoL3Rva2VuIiwiemlkIjoidWFhIiwiYXVkIjpbImFkbWluIiwiY2xpZW50cyIsInVhYSIsInNjaW0iXX0.SZvhSsc0qmquQU4ojkUJTiEt_HCkUFPbTPE233AX4jmuTXUkfAhyCToeL2huEF4qrPlZ5pPJ_pvNYwhKfu0xXmMnMDDce6XQ_e_FP3fJWuhyMQ8T2ZlUdn-W9d4O89RecPoSFpr8dp6ttnLbIr8d3_LWQQ80HsRdom8Z5ek6lr5hcNfCyxmSgKLa7rbb8fxd0NkIiDAkgxrGuT6Thr8hh0wqC5p5P8xv3Ncxaenado4GIZeQf7Ek9UTmMuarnD0BT6GYu3NRLlB9ZKy8j2MhoCr5fqTeA13ywm1Secph1L7wc2IaZMlFG9eo0njz7QamLLcBJWmsagENXMztOiI6NQ"
}

Use Ruby, Python, or similar to parse the OAuth 2.0 JSON response and extract the JWT access token.

require 'json'
JSON.parse(access_token)['access_token']
eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiJiMDkzYmYzZmVkYjY0YzU0OWM5MTBiNmJiMmNlYjg2NSIsInN1YiI6ImFkbWluIiwiYXV0aG9yaXRpZXMiOlsiY2xpZW50cy5yZWFkIiwiY2xpZW50cy5zZWNyZXQiLCJjbGllbnRzLndyaXRlIiwidWFhLmFkbWluIiwiY2xpZW50cy5hZG1pbiIsInNjaW0ud3JpdGUiLCJzY2ltLnJlYWQiXSwic2NvcGUiOlsiY2xpZW50cy5yZWFkIiwiY2xpZW50cy5zZWNyZXQiLCJjbGllbnRzLndyaXRlIiwidWFhLmFkbWluIiwiY2xpZW50cy5hZG1pbiIsInNjaW0ud3JpdGUiLCJzY2ltLnJlYWQiXSwiY2xpZW50X2lkIjoiYWRtaW4iLCJjaWQiOiJhZG1pbiIsImF6cCI6ImFkbWluIiwiZ3JhbnRfdHlwZSI6ImNsaWVudF9jcmVkZW50aWFscyIsInJldl9zaWciOiI5N2M1MDBiYiIsImlhdCI6MTQ2OTU2MzU3MiwiZXhwIjoxNDY5NjA2NzcyLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvdWFhL29hdXRoL3Rva2VuIiwiemlkIjoidWFhIiwiYXVkIjpbImFkbWluIiwiY2xpZW50cyIsInVhYSIsInNjaW0iXX0.iwI9YI6I2CK-B706GazOsYfdM83E5DfUIW5nm0NGu0c6XjNgLZzFjwuMp_AQfZwcG15xU-QTeg6tITyiqml29mZin6R_VuxJPVva4HXuB2tpuNX7wGHQs6iVNSMQZKngfUuOBx-3VdnDmPiNfo9z9bKC9uxKuHYfFNGZe4KlWWk8yLcwSZL7Wai-hrfGkaPfKe7GpqeCR4wr7dOn-9BcVmfRgFF8si7asXAiRvOs5ESH74w_0AW5-yZYvFNHs8g77R6GxP_CURaqofgufrcfPAV3x9MnSRDPy19BC3d4BSBug8Nm8Aq6Zla1dylevOHi2aSY_-eLeNl-d1zQXJnLHw

Create Keti admin

Create an OAuth client that we can use to consume the Keti RESTful API.

POST http://localhost:8080/uaa/oauth/clients
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json

{
  "name" : "ACS admin",
  "authorities" : [
    "acs.attributes.read",
    "acs.attributes.write",
    "acs.policies.read",
    "acs.policies.write",
    "acs.zones.admin",
    "predix-acs.zones.demo.admin",
    "predix-acs.zones.demo.user" ],
  "authorized_grant_types" : [ "client_credentials" ],
  "client_id" : "acs_admin",
  "client_secret" : "acs_admin_secret",
  "scope" : [ "uaa.none" ]
}
{
  "lastModified": 1469563591343,
  "name": "ACS admin",
  "authorities": [
    "acs.policies.read",
    "acs.policies.write",
    "acs.attributes.read",
    "predix-acs.zones.demo.user",
    "acs.attributes.write",
    "acs.zones.admin",
    "predix-acs.zones.demo.admin"
  ],
  "action": "none",
  "autoapprove": [],
  "authorized_grant_types": [
    "client_credentials"
  ],
  "resource_ids": [
    "none"
  ],
  "client_id": "acs_admin",
  "scope": [
    "uaa.none"
  ]
}

Setting up ACS

Running ACS

  • Start ACS
service/start-acs-public-graph.sh

Creating an ACS zone

  • Get ACS admin token
POST http://localhost:8080/uaa/oauth/token
Authorization: Basic YWNzX2FkbWluOmFjc19hZG1pbl9zZWNyZXQ=

grant_type=client_credentials
{
  "jti": "d937401207364668a83a2ed506f70ce0",
  "scope": "acs.policies.read acs.policies.write acs.attributes.read predix-acs.zones.demo.user acs.attributes.write acs.zones.admin predix-acs.zones.demo.admin",
  "expires_in": 43199,
  "token_type": "bearer",
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiJkOTM3NDAxMjA3MzY0NjY4YTgzYTJlZDUwNmY3MGNlMCIsInN1YiI6ImFjc19hZG1pbiIsImF1dGhvcml0aWVzIjpbImFjcy5wb2xpY2llcy5yZWFkIiwiYWNzLnBvbGljaWVzLndyaXRlIiwiYWNzLmF0dHJpYnV0ZXMucmVhZCIsInByZWRpeC1hY3Muem9uZXMuZGVtby51c2VyIiwiYWNzLmF0dHJpYnV0ZXMud3JpdGUiLCJhY3Muem9uZXMuYWRtaW4iLCJwcmVkaXgtYWNzLnpvbmVzLmRlbW8uYWRtaW4iXSwic2NvcGUiOlsiYWNzLnBvbGljaWVzLnJlYWQiLCJhY3MucG9saWNpZXMud3JpdGUiLCJhY3MuYXR0cmlidXRlcy5yZWFkIiwicHJlZGl4LWFjcy56b25lcy5kZW1vLnVzZXIiLCJhY3MuYXR0cmlidXRlcy53cml0ZSIsImFjcy56b25lcy5hZG1pbiIsInByZWRpeC1hY3Muem9uZXMuZGVtby5hZG1pbiJdLCJjbGllbnRfaWQiOiJhY3NfYWRtaW4iLCJjaWQiOiJhY3NfYWRtaW4iLCJhenAiOiJhY3NfYWRtaW4iLCJncmFudF90eXBlIjoiY2xpZW50X2NyZWRlbnRpYWxzIiwicmV2X3NpZyI6ImQ4NTlkYThmIiwiaWF0IjoxNDY5MTQ3OTE5LCJleHAiOjE0NjkxOTExMTksImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC91YWEvb2F1dGgvdG9rZW4iLCJ6aWQiOiJ1YWEiLCJhdWQiOlsiYWNzX2FkbWluIiwiYWNzLnBvbGljaWVzIiwiYWNzLmF0dHJpYnV0ZXMiLCJwcmVkaXgtYWNzLnpvbmVzLmRlbW8iLCJhY3Muem9uZXMiXX0.wLH3RTAEGP4MR6F6C53y02s3VtsR_DNXfSs0W3BMT4LkR2jMUJD5HBK7n2hXDhTgaRMtlsQQFWbGYTGfefjpFkmpwHsLfd1_yCxuqisDANF98ee9QbtU2ZOzstsoFkjopd-YeKphDTCLuccl19ToRMYkNTEGV1DswEJjMAU3bnF9VQOleHyS308k-jOEOXiCZnhHihoZbUDv1kn6j8RZusfFZqVm6zowpKaKg8EewdA1duPKlhn_5UWVPhmSYdYTCFyEYG9--RpPmc16L0hojpbUwDDsuTUgyVbR87USfMxBmrBGANiT-Dz8QBysfBhwweA1EFpBjNrOnO2rA8Sz9w"
}
require 'json'
JSON.parse(access_token)['access_token']
eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiJkZTJlYjU4Y2VhMGU0ODJlODE2NTRmNzZiYmJiNzA3MCIsInN1YiI6ImFjc19hZG1pbiIsImF1dGhvcml0aWVzIjpbImFjcy5wb2xpY2llcy5yZWFkIiwiYWNzLnBvbGljaWVzLndyaXRlIiwiYWNzLmF0dHJpYnV0ZXMucmVhZCIsInByZWRpeC1hY3Muem9uZXMuZGVtby51c2VyIiwiYWNzLmF0dHJpYnV0ZXMud3JpdGUiLCJhY3Muem9uZXMuYWRtaW4iLCJwcmVkaXgtYWNzLnpvbmVzLmRlbW8uYWRtaW4iXSwic2NvcGUiOlsiYWNzLnBvbGljaWVzLnJlYWQiLCJhY3MucG9saWNpZXMud3JpdGUiLCJhY3MuYXR0cmlidXRlcy5yZWFkIiwicHJlZGl4LWFjcy56b25lcy5kZW1vLnVzZXIiLCJhY3MuYXR0cmlidXRlcy53cml0ZSIsImFjcy56b25lcy5hZG1pbiIsInByZWRpeC1hY3Muem9uZXMuZGVtby5hZG1pbiJdLCJjbGllbnRfaWQiOiJhY3NfYWRtaW4iLCJjaWQiOiJhY3NfYWRtaW4iLCJhenAiOiJhY3NfYWRtaW4iLCJncmFudF90eXBlIjoiY2xpZW50X2NyZWRlbnRpYWxzIiwicmV2X3NpZyI6ImQ4NTlkYThmIiwiaWF0IjoxNDY5MTQ3OTQxLCJleHAiOjE0NjkxOTExNDEsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC91YWEvb2F1dGgvdG9rZW4iLCJ6aWQiOiJ1YWEiLCJhdWQiOlsiYWNzX2FkbWluIiwiYWNzLnBvbGljaWVzIiwiYWNzLmF0dHJpYnV0ZXMiLCJwcmVkaXgtYWNzLnpvbmVzLmRlbW8iLCJhY3Muem9uZXMiXX0.lNUF-oLqCq0EAHRmgY-zXunVkMnNewarq2PC0KrC_SbD3NGozDEDdKaW9oCIeGJTy92M3LEk6CuF96F7Jyn4VJtwKGsounkaKB9WHpyZVYDa7H9eMBasCOO75YKqum2Pi288wbV5anUdzmVF136QNtr3asPyEfFT6qTins3-6Tm1GjxzbYLCzbVW53W-RsbQuXV750AnMf4AU1Odo5UJIQZgomqQnvWofoLPndaXK0lYL_k_d3Fhntflmk0qvYXlUS6U_FfX8GsqjKnlaL2gbsRVKNM9JdMU4np6WDT53b6USotuHC2HTIDZ36tnT8AhkcycFqZzd7nblcST_G5hjQ
  • Create ACS zone. ACS is a multi-tenant service. For mysterious reasons, we’ve adopted the term “zone” for each separate ACS tenancy. Before you can start using ACS you have to create a zone. In this example, we create a zone called “demo”.
PUT http://localhost:8181/v1/zone/demo
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json

{
  "name" : "demo",
  "description" : "demo",
  "subdomain" : "demo"
}
HTTP/1.1 201 Created
Date: Fri, 22 Jul 2016 00:54:02 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: 7c4b28d6-c252-4a7e-bf8f-1594e9a9efe3
X-Application-Context: application:h2,public,simple-cache,graph:8181
Content-Length: 0
Server: Jetty(9.2.15.v20160210)

Simple group-based access control example

Create a subject and set the subject attributes

PUT http://localhost:8181/v1/subject/tom%40ge.com
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "subjectIdentifier" : "tom@ge.com",
  "attributes" : [
    {
      "issuer" : "https://acs.predix.io",
      "name"   : "org",
      "value"  : "ge"
    },
    {
      "issuer" : "https://acs.predix.io",
      "name"   : "group",
      "value"  : "research"
    },
    {
      "issuer" : "https://acs.predix.io",
      "name"   : "role",
      "value"  : "analyst"
    }
  ]
}
HTTP/1.1 201 Created
Date: Fri, 22 Jul 2016 00:54:11 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: 623880ec-dc83-4616-8aed-d82c48504ebe
X-Application-Context: application:h2,public,simple-cache,graph:8181
Location: /subject/tom@ge.com
Content-Length: 0
Server: Jetty(9.2.15.v20160210)

Create a resource and set the resource attributes

PUT http://localhost:8181/v1/resource/%2fengines%2f9
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "subjectIdentifier" : "/engines/9",
  "attributes" : [
    {
      "issuer" : "https://acs.predix.io",
      "name"   : "org",
      "value"  : "ge"
    },
    {
      "issuer" : "https://acs.predix.io",
      "name"   : "group",
      "value"  : "research"
    }
  ]
}
HTTP/1.1 201 Created
Date: Fri, 22 Jul 2016 00:54:21 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: 8371bd64-9562-430e-b60a-8ef7292154f5
X-Application-Context: application:h2,public,simple-cache,graph:8181
Location: /resource//engines/9
Content-Length: 0
Server: Jetty(9.2.15.v20160210)

Create a policy set

PUT http://localhost:8181/v1/policy-set/default
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "name" : "default",
  "policies" : [
    {
      "name" : "Analysts can access engines if they belong to the same group.",
      "target" : {
        "resource" : {
          "name" : "Engine",
          "uriTemplate" : "/engines/{engine_id}"
        },
        "action" : "GET",
        "subject" : {
          "name" : "Analysts",
          "attributes" : [
            {
              "issuer" : "https://acs.predix.io",
              "name"   : "role",
              "value"  : "analyst"
            }
          ]
        }
      },
      "conditions" : [
        { 
          "name"      : "is a member of the same group",
          "condition" : "resource.and(subject).haveSame('https://acs.predix.io', 'group').result()" 
        }
      ],
      "effect" : "PERMIT"
    },
    {
      "name" : "Deny all other requests.",
      "effect" : "DENY"
    }
  ]
}
HTTP/1.1 201 Created
Date: Fri, 22 Jul 2016 00:54:33 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: 14a07d7b-41e7-43c0-b79d-77e3927d0294
X-Application-Context: application:h2,public,simple-cache,graph:8181
Location: /policy-set/default
Content-Length: 0
Server: Jetty(9.2.15.v20160210)

Submit a authorization request for policy evaluation

POST http://localhost:8181/v1/policy-evaluation
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "action" : "GET",
  "resourceIdentifier" : "/engines/9",
  "subjectIdentifier" : "tom@ge.com"
}
{
  "timestamp": 0,
  "resolvedResourceUris": [
    "\/engines\/9"
  ],
  "resourceAttributes": [
    {
      "value": "ge",
      "name": "org",
      "issuer": "https:\/\/acs.predix.io"
    },
    {
      "value": "research",
      "name": "group",
      "issuer": "https:\/\/acs.predix.io"
    }
  ],
  "subjectAttributes": [
    {
      "value": "analyst",
      "name": "role",
      "issuer": "https:\/\/acs.predix.io"
    },
    {
      "value": "ge",
      "name": "org",
      "issuer": "https:\/\/acs.predix.io"
    },
    {
      "value": "research",
      "name": "group",
      "issuer": "https:\/\/acs.predix.io"
    }
  ],
  "effect": "PERMIT"
}

Hierarchical attributes with dynamic role example

Create a subject role

This subject represents the analyst role.

PUT http://localhost:8181/v1/subject/role-analyst
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "subjectIdentifier" : "role-analyst",
  "attributes" : [
    {
      "issuer" : "https://acs.predix.io",
      "name"   : "role",
      "value"  : "analyst"
    }
  ]
}
HTTP/1.1 201 Created
Date: Fri, 22 Jul 2016 00:43:24 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: 1d06af08-3d01-4892-8957-5d455002441e
X-Application-Context: application:h2,public,simple-cache,graph:8181
Location: /subject/role-analyst
Content-Length: 0
Server: Jetty(9.2.15.v20160210)

Create a subject user

This user will inherit the analyst role only when accessing engines in the san-ramon site.

PUT http://localhost:8181/v1/subject/tom%40ge.com
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "subjectIdentifier" : "tom@ge.com",
  "parents" : [
    {
      "identifier" : "role-analyst",
      "scopes" : [
        {
          "issuer" : "https://acs.predix.io",
          "name"   : "site",
          "value"  : "san-ramon"
        }
      ]
    }
  ]
}
HTTP/1.1 204 No Content
Date: Fri, 22 Jul 2016 00:43:43 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: 92053b82-9458-49ca-8b0e-aba3ba18c84c
X-Application-Context: application:h2,public,simple-cache,graph:8181
Location: /subject/tom@ge.com
Server: Jetty(9.2.15.v20160210)

Create a resource site

PUT http://localhost:8181/v1/resource/%2fsites%2fsan-ramon
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "subjectIdentifier" : "/sites/san-ramon",
  "attributes" : [
    {
      "issuer" : "https://acs.predix.io",
      "name"   : "site",
      "value"  : "san-ramon"
    }
  ]
}
HTTP/1.1 201 Created
Date: Fri, 22 Jul 2016 00:44:06 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: 03febd4b-ef28-43b7-9c76-37663cd393b1
X-Application-Context: application:h2,public,simple-cache,graph:8181
Location: /resource//sites/san-ramon
Content-Length: 0
Server: Jetty(9.2.15.v20160210)

Create a resource engine in the san-ramon site

PUT http://localhost:8181/v1/resource/%2fengines%2f9
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "subjectIdentifier" : "/engines/9",
  "parents" : [
    {
      "identifier" : "/sites/san-ramon"
    }
  ]
}
HTTP/1.1 204 No Content
Date: Fri, 22 Jul 2016 00:44:23 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: ca036e30-2f17-4287-981c-0ca5731999bc
X-Application-Context: application:h2,public,simple-cache,graph:8181
Location: /resource//engines/9
Server: Jetty(9.2.15.v20160210)

Create a resource engine that is not in the san-ramon site

PUT http://localhost:8181/v1/resource/%2fengines%2f11
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "subjectIdentifier" : "/engines/11"
}
HTTP/1.1 201 Created
Date: Fri, 22 Jul 2016 00:44:39 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: 2fcb9168-ee4f-4953-aa3d-fcd944de1a44
X-Application-Context: application:h2,public,simple-cache,graph:8181
Location: /resource//engines/11
Content-Length: 0
Server: Jetty(9.2.15.v20160210)

Create a policy set

PUT http://localhost:8181/v1/policy-set/default
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "name" : "default",
  "policies" : [
    {
      "name" : "Analysts can access engines.",
      "target" : {
        "resource" : {
          "name" : "Engine",
          "uriTemplate" : "/engines/{engine_id}"
        },
        "action" : "GET",
        "subject" : {
          "name" : "Analysts",
          "attributes" : [
            {
              "issuer" : "https://acs.predix.io",
              "name"   : "role",
              "value"  : "analyst"
            }
          ]
        }
      },
      "conditions" : [
        { 
          "name"      : "is an analyst",
          "condition" : "match.single(subject.attributes('https://acs.predix.io', 'role'), 'analyst')" 
        }
      ],
      "effect" : "PERMIT"
    },
    {
      "name" : "Deny all other requests.",
      "effect" : "DENY"
    }
  ]
}
HTTP/1.1 201 Created
Date: Fri, 22 Jul 2016 00:44:57 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Correlation-Id: c22d3f09-4f0a-4b3c-a38d-0286f4eb4780
X-Application-Context: application:h2,public,simple-cache,graph:8181
Location: /policy-set/default
Content-Length: 0
Server: Jetty(9.2.15.v20160210)

Submit a permitted authorization request for policy evaluation

POST http://localhost:8181/v1/policy-evaluation
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "action" : "GET",
  "resourceIdentifier" : "/engines/9",
  "subjectIdentifier" : "tom@ge.com"
}
{
  "timestamp": 0,
  "resolvedResourceUris": [
    "\/engines\/9"
  ],
  "resourceAttributes": [
    {
      "value": "san-ramon",
      "name": "site",
      "issuer": "https:\/\/acs.predix.io"
    }
  ],
  "subjectAttributes": [
    {
      "value": "analyst",
      "name": "role",
      "issuer": "https:\/\/acs.predix.io"
    }
  ],
  "effect": "PERMIT"
}

Submit a denied authorization request for policy evaluation

POST http://localhost:8181/v1/policy-evaluation
Authorization: bearer ${access_token}
Accept: application/json
Content-Type: application/json
Predix-Zone-Id: demo

{
  "action" : "GET",
  "resourceIdentifier" : "/engines/11",
  "subjectIdentifier" : "tom@ge.com"
}
{
  "timestamp": 0,
  "resolvedResourceUris": [
    "\/engines\/11"
  ],
  "resourceAttributes": [],
  "subjectAttributes": [],
  "effect": "DENY"
}