Policy Enforcement

ABAC & Open Policy Agent

How Tessera evaluates every decryption request in real time against the requester's clearance attributes — using Open Policy Agent as the Policy Decision Point inside the Key Access Service.

The Access Control Challenge

A classified file may be stored on a shared drive, emailed to a partner organisation, archived in a document management system, or transferred across a domain boundary. At every one of those points, the file is accessible to systems — and potentially people — that are not authorised to read it.

Traditional access control — file permissions, ACLs, role-based group membership — is attached to the storage system, not the data. Once a file moves, the access control does not move with it. The protection is gone.

Tessera inverts this by embedding the access policy inside the encrypted file, cryptographically bound so it cannot be separated from the content. The policy is evaluated by the Key Access Service (KAS) at the moment of decryption, against the live attributes of the requester. The file decrypts only if every policy condition is satisfied — and that evaluation is performed fresh every time, never cached.

The model that makes this precise and auditable is Attribute-Based Access Control (ABAC). The engine that evaluates the policy is Open Policy Agent (OPA).

The Attribute Model

An ABAC decision requires two sets of attributes: the resource attributes — what the file requires — and the subject attributes — what the requester holds. Both sets are expressed as structured URIs so they can be compared unambiguously by the policy engine.

Resource Attributes — the Policy

Derived from the STANAG 4774 Confidentiality Label. The label's classification level, categories, and releasability markings are translated — via the domain XMLSPIF — into required attribute URIs that are embedded as the ABAC policy inside the .ztdf archive.

A NATO SECRET / REL GBR document produces required attributes for classification/value/secret and relto/value/gbr. Both must be satisfied.

Subject Attributes — the Clearance

Carried in the requester's JWT access token, issued by the identity provider after authentication. The token contains the user's clearance level, category authorisations, COI memberships, and releasability markings as structured claims presented to the KAS on every request.

A user cleared to NATO SECRET with GBR releasability holds attributes classification/value/secret and relto/value/gbr in their token.

Attribute URI Namespace

All attribute values are expressed as URIs under a shared https://nato.int/attr/ namespace, following the structure https://nato.int/attr/<tag-set>/value/<value>. A shared namespace means a .ztdf file protected on one system can be evaluated by a partner KAS without translation — both understand the same attribute identifiers.

From Label to Policy

When a file is protected, the STANAG 4774 Confidentiality Label does not merely accompany the file — it drives the access policy. The XMLSPIF maps each label value to an attribute URI, and those URIs become the required attributes of the ABAC policy embedded in the .ztdf archive.

STANAG 4774 Label
XMLSPIF translation
Classification level attribute URI
Category bits attribute URIs
Releasability attribute URIs
ACP-240 policy
Embedded in .ztdf manifest
HMAC-bound to DEK
Tamper-evident

The HMAC binding is critical: the policy is bound to the Data Encryption Key using HMAC-SHA256. Any attempt to alter the policy — to relax a restriction and gain access — invalidates the binding and the KAS refuses to proceed. The policy and the encrypted payload are inseparable.

Open Policy Agent

Open Policy Agent (OPA) is a CNCF-graduated open-source policy engine. It evaluates structured queries against Rego policies — a declarative language purpose-built for access control — and returns a structured decision. Tessera uses OPA as the Policy Decision Point (PDP) inside the KAS.

Policy as Code

Rego rules are readable, version-controlled, and independently testable. The policy is entirely separate from the KAS application code — the KAS asks OPA for a decision, it does not implement the evaluation itself.

Live Policy Updates

Policy bundles are distributed by the Management Service and loaded by each KAS instance at runtime. Policy can be updated and pushed to all KAS instances without restarting the service.

Auditable Decisions

OPA produces a structured decision record for every evaluation: the input attributes, the rules invoked, and the outcome. This feeds the full audit trail required by ACP-240 Supp-2.

Why OPA rather than custom ABAC code?

Custom ABAC implementations are difficult to audit and easy to get wrong. OPA cleanly separates the policy decision from the application logic. This means security administrators can review, test, and update policy rules without touching the KAS codebase — satisfying the two-person scrutiny requirement of ACP-240 Supp-2, where policy changes require independent review before they can be pushed to production.

Policy Evaluation Flow

Every decryption request follows the same evaluation path. No step can be skipped, and any failure at any step results in a DENY — no key is released and no reason that could assist an attacker is disclosed.

  1. Authentication — The client presents a signed JWT access token to the KAS, together with a DPoP proof (RFC 9449) that cryptographically binds the token to the client's ephemeral keypair, preventing token replay from a different client.
  2. Token verification — The KAS validates the JWT signature against the identity provider's JWKS. An expired, tampered, or unrecognised token produces an immediate 401.
  3. Attribute extraction — The KAS extracts the user's clearance attributes from the validated JWT claims and normalises them to the shared attribute URI namespace.
  4. Policy binding verification — The KAS verifies the HMAC-SHA256 policy binding in the .ztdf manifest. This confirms the ABAC policy has not been altered since the file was encrypted.
  5. OPA evaluation — The KAS submits the user's attribute set and the resource's required attribute set to OPA. The Rego policy evaluates whether every required attribute is present and satisfied.
  6. Decision — OPA returns ALLOW or DENY. On ALLOW, the KAS unwraps the Data Encryption Key and re-wraps it with the client's ephemeral public key for secure delivery. On DENY, a 403 is returned with no key material in the response.
Client + JWT
Key Access Service
Verify JWT & DPoP proof
Extract clearance attributes from token
Verify HMAC policy binding
Submit to OPA → Rego evaluation
ALLOW → rewrap DEK DENY → 403, no key

Policy Distribution and Management

OPA policy is not hardcoded in the KAS. Rego rules are compiled into OPA bundles and distributed to all KAS instances by the Management Service. This separates policy authoring from service deployment and supports the two-person scrutiny model required by ACP-240 Supp-2.

  • Security administrators author and peer-review Rego rules in the Management Console. An approved bundle requires sign-off before it can be pushed — no single administrator can push a policy change unilaterally.
  • An approved bundle is distributed to all registered KAS instances. The KAS reloads the bundle at runtime without restarting; all subsequent evaluations use the updated rules.
  • Each KAS instance verifies the bundle's content hash against the Management Service's signed manifest before loading. A bundle with a mismatched hash is rejected.
Standalone KAS — Cross-Domain Deployment

A KAS operating in an isolated High-Side zone has no Management Service connection. It ships with a pre-built, pre-approved OPA bundle compiled for that specific deployment. Policy updates require a controlled maintenance window and a fresh approval cycle — by design, not by limitation. The isolation ensures that High-Side policy cannot be altered from the Low Side.

Multi-Domain Scenarios

When a .ztdf archive contains Key Access Objects (KAOs) pointing to multiple KAS instances — each responsible for a different security domain or Community of Interest — the ABAC evaluation at each KAS is independent and domain-scoped.

The enterprise KAS brokers requests to domain-specific KAS instances on behalf of the client. Each domain KAS runs its own Rego policy tailored to that domain's clearance requirements. The client receives DEK fragments from each KAS and combines them — a complete key is produced only if every domain KAS grants access.

Any-Of Mode

Multiple KAOs share the same session identifier. Any single KAS that grants access can release the full DEK. Used for high-availability: if the primary KAS is unreachable, a secondary KAS operating under the same policy can fulfil the request.

All-Of Mode

Multiple KAOs carry different session identifiers. Every KAS in the set must grant access before the DEK fragments can be combined. Used for compartmented access: a document shared with a COI requires both the base clearance KAS and the COI-specific KAS to independently approve.