Back to all resources
KBAC KBAC Python

KBAC: authZEN + advice.

Create a policy with a step up if the user does not have enough authorization and execute KBAC query.

KBAC: authZEN + advice.

Create a policy and run a KBAC query. An advice is answered if the user does not have enough authorization.

Use case

When a user requests access to their Profile resource, an authorization check should happen, which must check the

user's current authentication level against a minimum value. If the user's current authentication level is lesser than the level

required by the access policy, the KBAC engine should deny the action and also respond to the call with an Advice suggesting the

user should step-up their authentication level.

Create a policy which rules that a Person node can service a laptop if the Person node owns it and if the token of the Person node access Token

has not expired.

ikg

Requirements

- ServiceAccount credentials created in the IndyKite Hub for your organization.

- AppAgent credentials created in the IndyKite Hub, using the REST endpoints or using Terraform for your Project / Application.

- Auth0 user token for the user who requires access.

Steps

1. Using the AppAgent credential as API Key (name: X-IK-ClientKey), ingest data in your IKG (IndyKite Knowledge Graph) using the script provided.

2. Using the ServiceAccount credential as Bearer token, create a KBAC Policy.

3. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a KBAC authZEN Evaluation which returns step up.

4. Using the AppAgent credential as API Key (name: X-IK-ClientKey), run a KBAC authZEN Evaluation which gives access.

5. Delete your configuration.

6. Try with your own data.

Step 1

Ingest the nodes needed for this use case.

POST https://eu.api.indykite.com/capture/v1/nodes/Json
{
  "nodes": [
    {
      "external_id": "alice",
      "is_identity": true,
      "type": "Person",
      "properties": [
        {
          "type": "email",
          "value": "alice@email.com"
        },
        {
          "type": "given_name",
          "value": "Alice"
        },
        {
          "type": "last_name",
          "value": "Smith"
        }
      ]
    },
    {
      "external_id": "knightrider",
      "type": "Person",
      "is_identity": true,
      "properties": [
        {
          "type": "email",
          "value": "knightrider@demo.com"
        },
        {
          "type": "name",
          "value": "Michael Knight"
        }
      ]
    },
    {
      "external_id": "satchmo",
      "type": "Person",
      "is_identity": true,
      "properties": [
        {
          "type": "email",
          "value": "satchmo@demo.com"
        },
        {
          "type": "name",
          "value": "Louis Armstrong"
        }
      ]
    },
    {
      "external_id": "karel",
      "type": "Person",
      "is_identity": true,
      "properties": [
        {
          "type": "email",
          "value": "karel@demo.com"
        },
        {
          "type": "name",
          "value": "Karel Plihal"
        }
      ]
    },
    {
      "external_id": "kitt",
      "type": "Car",
      "is_identity": false,
      "properties": [
        {
          "type": "manufacturer",
          "value": "pontiac"
        },
        {
          "type": "model",
          "value": "Firebird"
        }
      ]
    },
    {
      "external_id": "cadillacv16",
      "type": "Car",
      "is_identity": false,
      "properties": [
        {
          "type": "manufacturer",
          "value": "Cadillac"
        },
        {
          "type": "model",
          "value": "V-16"
        }
      ]
    },
    {
      "external_id": "harmonika",
      "type": "Bus",
      "is_identity": false,
      "properties": [
        {
          "type": "manufacturer",
          "value": "Ikarus"
        },
        {
          "type": "model",
          "value": "280"
        }
      ]
    },
    {
      "external_id": "listek",
      "type": "Ticket",
      "is_identity": false
    },
    {
      "external_id": "airbook-xyz",
      "type": "Laptop",
      "is_identity": false
    }
  ]
}

Ingest the relationships needed for this use case.

POST https://eu.api.indykite.com/capture/v1/relationships/Json
{
  "relationships": [
    {
      "source": {
        "external_id": "knightrider",
        "type": "Person"
      },
      "target": {
        "external_id": "kitt",
        "type": "Car"
      },
      "type": "DRIVES"
    },
    {
      "source": {
        "external_id": "satchmo",
        "type": "Person"
      },
      "target": {
        "external_id": "cadillacv16",
        "type": "Car"
      },
      "type": "DRIVES"
    },
    {
      "source": {
        "external_id": "karel",
        "type": "Person"
      },
      "target": {
        "external_id": "listek",
        "type": "Ticket"
      },
      "type": "HAS"
    },
    {
      "source": {
        "external_id": "listek",
        "type": "Ticket"
      },
      "target": {
        "external_id": "harmonika",
        "type": "Bus"
      },
      "type": "FOR"
    },
    {
      "source": {
        "external_id": "karel",
        "type": "Person"
      },
      "target": {
        "external_id": "airbook-xyz",
        "type": "Laptop"
      },
      "type": "OWNS"
    },
    {
      "source": {
        "external_id": "alice",
        "type": "Person"
      },
      "target": {
        "external_id": "airbook-xyz",
        "type": "Laptop"
      },
      "type": "OWNS"
    },
    {
      "source": {
        "external_id": "knightrider",
        "type": "Person"
      },
      "target": {
        "external_id": "kitt",
        "type": "Car"
      },
      "type": "OWNS"
    },
    {
      "source": {
        "external_id": "alice",
        "type": "Person"
      },
      "target": {
        "external_id": "cadillacv16",
        "type": "Car"
      },
      "type": "DRIVES"
    }
  ]
}

Step 2

KBAC Policy which rules that a Person node can service a laptop if the Person node owns it and if the external_id of the subject Person node is equal to the token sub.

policy.jsonJson
{
  "meta": {
    "policy_version": "2.0-kbac"
  },
  "subject": {
    "type": "Token"
  },
  "actions": [
    "CAN_SERVICE"
  ],
  "resource": {
    "type": "Laptop"
  },
  "condition": {
    "cypher": "MATCH (subject:Token)-[:_SAME_AS]->(person:Person)-[:OWNS]->(resource)",
    "filter": {
      "attribute": "$token.exp",
      "operator": ">",
      "value": 1773162816,
      "advice": {
        "error": "insufficient_user_authentication",
        "error_description": "Authentication is expired",
        "sub": "$token.exp"
      }
    }
  }
}

Request to create the KBAC Policy configuration using REST.

POST https://eu.api.indykite.com/configs/v1/authorization-policiesJson
{
  "project_id": "your_project_gid",
  "description": "description of policy",
  "display_name": "policy name",
  "name": "policy-name",
  "policy": "{\"meta\":{\"policy_version\":\"2.0-kbac\"},\"subject\":{\"type\":\"Token\"},\"actions\":[\"CAN_SERVICE\"],\"resource\":{\"type\":\"Laptop\"},\"condition\":{\"cypher\":\"MATCH (subject:Token)-[:_SAME_AS]->(person:Person)-[:OWNS]->(resource)\",\"filter\":{\"attribute\":\"$token.exp\",\"operator\":\">\",\"value\":1773162816,\"advice\":{\"error\":\"insufficient_user_authentication\",\"error_description\":\"Authentication is expired\",\"sub\":\"$token.exp\"}}}}",
  "status": "ACTIVE",
  "tags": []
}

Request to create the KBAC Policy configuration using REST.

policy_request.pyPython

import http.client

conn = http.client.HTTPSConnection("eu.api.indykite.com")

payload = "{"description": "",
  "display_name": "",
  "name": "",
  "policy": "",
  "project_id": "",
  "status": "ACTIVE",
  "tags": [
    ""
  ]}"
headers = {
    'Content-Type': "application/json",
    'Authorization': "YOUR_SECRET_TOKEN"
}

conn.request("POST", "/configs/v1/authorization-policies", payload, headers)
res = conn.getresponse()
data = res.read()

Request to read the KBAC Policy configuration using REST.

GET https://eu.api.indykite.com/configs/v1/authorization-policies/{id}Json
{
  "id": "your_policy_configuration_gid"
}

Request to read the KBAC Policy configuration using REST.

policy_request.pyPython

import http.client

conn = http.client.HTTPSConnection("eu.api.indykite.com")
headers = { 'Authorization': "YOUR_SECRET_TOKEN" }
conn.request("GET", "/configs/v1/authorization-policies/{{id}}", headers=headers)
res = conn.getresponse()
data = res.read()

Step 3

Run a KBAC authZEN Evaluation which returns step up.

POST /access/v1/evaluationsJson
{
  "subject": {
    "type": "Token",
    "id": "token_sub_value"
  },
  "resource": {
    "type": "Laptop",
    "id": "airbook-xyz"
  },
  "action": {
    "name": "CAN_SERVICE"
  }
}

Request to run KBAC authZEN Evaluation which returns step up.

evaluations.pyPython

import http.client

conn = http.client.HTTPSConnection("eu.api.indykite.com")

payload = "{
  	"subject": {"type": "Token",
        "id": "token_sub_value"}, 
    "resource": {"type": "Laptop",
        "id": "airbook-xyz"},
    "action": {"name": "CAN_SERVICE"}
}"

headers = {
    'Content-Type': "application/json",
    'Authorization': "Bearer eyJh....",
    'X-IK-ClientKey': "eyJh...."
}

conn.request("POST", "/access/v1/evaluation", payload, headers)

res = conn.getresponse()
data = res.read()

Response to the KBAC authZEN Evaluation request.

Response 200Json
{
  "context": {
    "advice": [
      {
        "error": "insufficient_user_authentication",
        "error_description": "Authentication is expired",
        "sub": "$token.exp"
      }
    ]
  },
  "decision": false
}

Step 4

Add the Person node access token in the headers:

key:Authorization value: Bearer access_token_value

Then run the same KBAC authZEN Evaluation.

POST https://eu.api.indykite.com/access/v1/evaluationsJson
{
  "subject": {
    "type": "Token",
    "id": "token_sub_value"
  },
  "resource": {
    "type": "Laptop",
    "id": "airbook-xyz"
  },
  "action": {
    "name": "CAN_SERVICE"
  }
}

Response to the KBAC authZEN Evaluation request.

Response 200Json
{
  "decision": true
}

Step 5

Delete the KBAC Policies.

DELETE https://eu.api.indykite.com/configs/v1/authorization-policies/{id}Json
{
  "id": "your_policy_configuration_gid"
}

Request to delete the KBAC Policies.

del.pyPython

import http.client

conn = http.client.HTTPSConnection("eu.api.indykite.com")

headers = { 'Authorization': "Bearer ...", 'Content-Type': "application/json" }

conn.request("DELETE", "/configs/v1/authorization-policies/{id}", headers=headers)

res = conn.getresponse()
data = res.read()

Tags

Authorization Security authZEN Step Up Advice authZEN Evaluation