Back to all guides
KBAC

What is AuthZEN?

Which problems AuthZEN requests solve and how to use them.

ikg

What is AuthZEN?

AuthZEN (AuthZ ENhancement) is an OpenID Foundation initiative that standardizes fine-grained authorization, similar to how OpenID Connect standardized authentication.

AuthZEN creates interoperability between:

  • Policy Enforcement Points (PEPs): Applications that need authorization decisions.
  • Policy Decision Points (PDPs): Services that evaluate policies and return decisions.

IndyKite is an AuthZEN-compliant PDP that uses its Identity Knowledge Graph (IKG) to make intelligent, context-aware authorization decisions.

Why use AuthZEN?

What problem does AuthZEN solve for interoperability?

Problem: The authorization landscape is fragmented. Different vendors use proprietary APIs, protocols, and policy languages, creating vendor lock-in and integration challenges.

AuthZEN's Solution: A standardized communication protocol between PEPs and PDPs. Any application can query any AuthZEN-compliant PDP, regardless of the underlying policy engine.

IndyKite Benefit: Organizations can use IndyKite's advanced KBAC capabilities alongside other AuthZEN-compliant components without vendor lock-in.

How does AuthZEN simplify development?

Problem: Developers often "reinvent the authorization wheel" for each application, leading to inconsistent implementations and security vulnerabilities.

AuthZEN's Solution: Standardized JSON-based request/response formats with core entities:

  • subject: Who is requesting access
  • action: What operation they want to perform
  • resource: What they want to access
  • context: Additional environmental data

IndyKite Benefit: Developers use the standard AuthZEN interface instead of learning a proprietary API, reducing integration time.

Why externalize authorization?

Problem: Embedding authorization logic in applications makes it difficult to manage, update, and audit. Fine-grained access control (e.g., "Can Alice view this specific document at this time?") becomes unscalable.

AuthZEN's Solution: Externalize authorization to dedicated PDPs that make dynamic, real-time decisions based on subject, resource, action, and context.

IndyKite Benefit: IndyKite's Identity Knowledge Graph enables complex, relationship-based authorization. Access decisions are based on "who you are, what you're trying to do, with what, from where, and why" — not just static roles.

How does AuthZEN improve security and compliance?

Problem: Inconsistent authorization creates security gaps and makes compliance difficult to demonstrate.

AuthZEN's Solution: Continuous authorization enforcement, dynamic separation of duties, and clear audit trails.

IndyKite Benefit: The IKG continuously updates with real-time data, enabling dynamic and adaptive access decisions that support "least privilege" and "zero trust" policies.

How do I make an AuthZEN request?

Single Evaluation Request

Endpoint:

  • EU: POST https://eu.api.indykite.com/access/v1/evaluation
  • US: POST https://us.api.indykite.com/access/v1/evaluation

Request Syntax

{
	"subject": {
		"type": "<string>",
		"id": "<string>"
	},
	"resource": {
		"type": "<string>",
		"id": "<string>"
	},
	"action": {
		"name": "<string>"
	},
	"context": {
		"input_params": {
			"<key>": "<value>"
		}
	}
}

What does each field mean?

Field Description Example
subject.type The type of entity requesting access (maps to node label in IKG) "User", "Service"
subject.id Unique identifier for the subject (maps to external_id in IKG) "alice@example.com"
resource.type The type of resource being accessed (maps to node label in IKG) "Document", "API"
resource.id Unique identifier for the resource (maps to external_id in IKG) "project_alpha_specs.pdf"
action.name The operation being requested "CAN_READ", "CAN_EDIT"
context.input_params Additional contextual data for policy evaluation. Also carries location parameters for 3.0-kbac policies on a composite IKG (see below) {"ip_address": "192.168.1.100"}, {"region": "east"}

Request Example

{
	"subject": {
		"type": "User",
		"id": "alice@example.com"
	},
	"resource": {
		"type": "Document",
		"id": "project_alpha_specs.pdf"
	},
	"action": {
		"name": "CAN_READ"
	},
	"context": {
		"input_params": {
			"ip_address": "192.168.1.100",
			"time_of_day": "14:30:00Z",
			"device_type": "laptop"
		}
	}
}

Response Syntax

{
	"decision": <boolean>,
	"context": {
		"advice": [{
			"error": "<string>",
			"error_description": "<string>"
		}]
	}
}

What does the response contain?

Field Description
decision true = access allowed, false = access denied
context.advice Optional array of advice objects explaining why access was denied
advice.error Error code (e.g., "insufficient_user_authentication")
advice.error_description Human-readable explanation of the denial

Response Example (Denied)

{
	"decision": false,
	"context": {
		"advice": [{
			"error": "insufficient_user_authentication",
			"error_description": "Authentication is expired"
		}]
	}
}

How does IndyKite process an AuthZEN request?

When IndyKite receives an AuthZEN request, it:

  1. Maps request to graph entities: The subject, resource, action, and context are mapped to nodes and relationships in the Identity Knowledge Graph.
  1. Evaluates KBAC policies: Policies defined as graph traversals are evaluated against real-time data.

    Example policy logic:

    • "Allow User to CAN_READ Document IF User IS_MEMBER_OF Team AND Document IS_ASSIGNED_TO Project AND Team IS_ASSIGNED_TO Project"
    • "Deny access IF context.ip_address is NOT in trusted_network"
  1. Returns decision: An AuthZEN-compliant response with decision (true/false) and optional advice explaining the decision.

How do I batch multiple evaluations?

Use the batch endpoint to evaluate multiple authorization requests in a single call.

Endpoint:

  • EU: POST https://eu.api.indykite.com/access/v1/evaluations
  • US: POST https://us.api.indykite.com/access/v1/evaluations

Batch Request Syntax

{
	"subject": {
		"type": "<string>",
		"id": "<string>"
	},
	"resource": {
		"type": "<string>",
		"id": "<string>"
	},
	"action": {
		"name": "<string>"
	},
	"context": {
		"input_params": {},
		"policy_tags": ["<string>"]
	},
	"evaluations": [{
		"subject": {
			"type": "<string>",
			"id": "<string>"
		},
		"resource": {
			"type": "<string>",
			"id": "<string>"
		},
		"action": {
			"name": "<string>"
		},
		"context": {
			"input_params": {},
			"policy_tags": ["<string>"]
		}
	}]
}

How do default values work in batch requests?

Fields defined at the top level serve as defaults for all evaluations. Each evaluation can override these defaults.

Field Required Description
subject Optional Default subject for all evaluations. Useful when the same user accesses multiple resources.
resource Optional Default resource for all evaluations. Overridden by evaluation-specific resource.
action Optional Default action for all evaluations. Overridden by evaluation-specific action.
context Optional Default context for all evaluations. Overridden by evaluation-specific context.
evaluations Required Array of individual evaluation objects to process.

What are policy_tags?

The policy_tags field allows you to filter which policies are evaluated for a request. Only policies with matching tags will be considered.

Batch Request Example

{
	"subject": {
		"type": "User",
		"id": "alice@example.com"
	},
	"action": {
		"name": "CAN_READ"
	},
	"evaluations": [
		{
			"resource": {
				"type": "Document",
				"id": "doc_001"
			}
		},
		{
			"resource": {
				"type": "Document",
				"id": "doc_002"
			}
		},
		{
			"resource": {
				"type": "Folder",
				"id": "folder_001"
			},
			"action": {
				"name": "CAN_LIST"
			}
		}
	]
}

This example evaluates:

  • Can Alice READ doc_001?
  • Can Alice READ doc_002?
  • Can Alice LIST folder_001? (overrides default action)

Which KBAC policy versions answer AuthZEN requests?

The decisions behind every AuthZEN endpoint come from KBAC policies. Two policy versions exist, selected by meta.policy_version in the policy JSON:

Aspect 2.0-kbac 3.0-kbac
Condition Cypher handling Rewritten by the platform into evaluation and search variants Raw: runs as authored; the platform only pins subject/resource and appends the projection
Composite-database routing (data residency) None: always the default database USE graph.byName(...) clauses, static or via location parameters supplied in context.input_params
Allowed Cypher clauses No CALL, no RETURN CALL { } subqueries and inner RETURNs allowed; mutating clauses still blocked
Policy JSON schema Identical: only meta.policy_version differs

A valid 2.0-kbac condition is also a valid 3.0-kbac condition: you can carry a policy over just by changing meta.policy_version, with two caveats: $subject_id must not be referenced (see below), and the platform-bound parameters ($subject_external_id, $subject_type, $resource_external_id, $resource_type) are bound automatically and never supplied via input_params.

$subject_id is not available in 3.0-kbac

A 3.0-kbac condition must not reference $subject_id: on a composite IKG the subject's internal node ID is not stable across locations, so 3.0-kbac identifies subjects by type and external ID only. Creating a policy that references it fails with 422 Unprocessable Entity:

{
	"message": "Unprocessable Entity",
	"errors": [
		"invalid policy config: parameter \"$subject_id\" is reserved and cannot be referenced"
	]
}

No replacement is needed: the platform already pins the subject by type and external ID in every 3.0-kbac query.

How do I request a decision in a specific location?

On a composite IKG (see the data residency guide), a 3.0-kbac policy can route with a dynamic parameter, for example USE graph.byName($region). The AuthZEN request then supplies the logical location (a key of the project's alias_mapping) through context.input_params: no new endpoint or field is involved:

{
	"subject": {
		"type": "Person",
		"id": "person-alice"
	},
	"resource": {
		"type": "Car",
		"id": "car-kitt"
	},
	"action": {
		"name": "CAN_DRIVE"
	},
	"context": {
		"input_params": {
			"region": "east"
		}
	}
}

This works identically on /access/v1/evaluation, /access/v1/evaluations (put the location in the default or per-evaluation context), and the three search endpoints.

Failure modes:

  • Omitting a required location parameter, passing a non-string, or naming a location that is not in alias_mapping fails the call with 422 Unprocessable Entity.
  • Using a location parameter against a project without a composite database fails with 422 Unprocessable Entity.
  • Bearer-token calls where the token's subject differs from the requested subject are denied with 403 Forbidden.

What credentials do I need?

  • AppAgent credentials: Required for all AuthZEN requests.
  • User access token: Required if subject is a user (not _Application).

Authentication header: X-IK-ClientKey: <AppAgent-token>

Next Steps