You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+7-6Lines changed: 7 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ Guidance for AI agents working in this repository. Read this before making chang
4
4
5
5
## What this is
6
6
7
-
Shared cross-service libraries for the Labs64.IO Ecosystem. Includes: the auth-context libraries (Java + Python), which parse, enforce and propagate the trusted gateway header contract, shared Spring Boot starters, plus the unified Cedar authorization assets: the shared schema/policies in `auth-policy-cedar/` and the `@Authorize`Cedar domain PEP in the Java starter (`io.labs64.authcontext.cedar`, feature-flagged via `labs64.auth.cedar.*`, engine = optional `com.cedarpolicy:cedar-java:uber` dependency).
7
+
Shared cross-service libraries for the Labs64.IO Ecosystem. Includes: the auth-context libraries (Java + Python), which parse, enforce and propagate the trusted gateway header contract, shared Spring Boot starters, plus the authorization assets: the engine-neutral `@Authorize` domain PEP in the Java starter (`io.labs64.authcontext.authorization`) with a Cerbos PDP client (`io.labs64.authcontext.cerbos`), feature-flagged via `labs64.auth.authz.*` (decisions delegated to the central Cerbos PDP over gRPC), the Cerbos-policy generator backend in `OpenApiAuthPreprocessor` (`--cerbos-output`/`--routes-output`), the decision-equivalence gate in `auth-policy-cerbos/`, and the `authz-queryplan-jpa` Data-PEP translator.
8
8
9
9
## Critical guardrails
10
10
@@ -14,16 +14,17 @@ Shared cross-service libraries for the Labs64.IO Ecosystem. Includes: the auth-c
14
14
4.**No mandatory runtime dependencies in the Python package.** FastAPI/httpx integrations import lazily; the core must stay dependency-free.
15
15
5.**Fail closed.** Non-public paths without a valid user identity return 401. Never weaken this default.
16
16
6.**Value sanitization pattern `^[a-zA-Z0-9_.:-]+$`** must match the ACS (traefik-authproxy) exactly.
17
-
7.**One Cedar schema.**`auth-policy-cedar/schema.cedarschema`is the single type system for BOTH authorization tiers (edge + every module's domain policies). Schema changes must keep `just cedar` green and stay in sync with `test-vectors/cedar-request-vectors.json` — the AuthContext→Cedar request contract the Java/Python PEPs are pinned to.
17
+
7.**OpenAPI is the single source of policy.** Cerbos policies are GENERATED from each module's `x-labs64-auth` by `OpenApiAuthPreprocessor` — never hand-edit generated policy YAML. Decision equivalence (edge + domain, incl. the cross-tenant isolation invariant) is proven by `auth-policy-cerbos/validate.sh` (`just cerbos`); keep it green.
→ GET /.well-known/auth-policy + /.well-known/auth-policy.cedar (runtime, served by the starter for the gateway ACS)
15
+
→ auth-context-spring-boot-starter (runtime enforcement via @Authorize interceptors and central Cerbos PDP)
17
16
```
18
17
19
18
1.**Author**: Add `x-labs64-auth` to each endpoint in your OpenAPI spec
20
-
2.**Build-time**: The preprocessor strips the extension, injects Java annotations (`@RequireTenant`, `@RequireScopes`, `@PublicEndpoint`) into the generated OpenAPI, and emits `auth-policy.cedar`
19
+
2.**Build-time**: The preprocessor strips the extension, injects Java annotations (`@RequireTenant`, `@RequireScopes`, `@PublicEndpoint`) into the generated OpenAPI, and emits Cerbos resource policies in YAML + routes manifest.
21
20
3.**Code generation**: OpenAPI Generator produces Java API interfaces with the injected annotations
22
21
4.**Runtime**: `auth-context-spring-boot-starter` auto-configures filters and interceptors that enforce the annotations
23
22
@@ -86,9 +85,9 @@ paths:
86
85
### Domain (Tier-2) resource authorization
87
86
88
87
Declare `resource: <Type>` to have the operation authorized in-process by the
89
-
module's `@Authorize` PEP against a typed Cedar resource. This is
88
+
module's `@Authorize` PEP against a typed Cerbos resource. This is
90
89
the OpenAPI-native source for the generated domain policy set
91
-
(`auth-policy-domain.cedar`): the preprocessor emits one `permit` keyed on the
90
+
(`auth-policy-domain.cerbos`): the preprocessor emits one `permit` keyed on the
92
91
operationId, conditioned on the same `tenant`/`scopes`, plus one structural
93
92
cross-tenant guard per resource type. Operations without `resource` are
94
93
edge-only (coarse reachability).
@@ -106,8 +105,8 @@ paths:
106
105
```
107
106
108
107
The resource `<Type>` must be declared in the shared schema
109
-
(`labs64.io-commons/auth-policy-cedar/schema.cedarschema`), and the module
110
-
supplies the resource's `tenant` at request time via a `CedarEntityResolver`.
108
+
(`labs64.io-commons/auth-policy-cerbos/schema.cerbosschema`), and the module
109
+
supplies the resource's `tenant` at request time via a `CerbosEntityResolver`.
111
110
Fine-grained resource-attribute rules (workflow status, ownership) are **not**
112
111
expressible from OpenAPI — they stay in the service layer (and later Postgres
113
112
RLS), by design.
@@ -131,14 +130,12 @@ Add three things to your `pom.xml`:
Both files are generated from the one `x-labs64-auth` source, so traefik and the
381
-
module enforce the same OpenAPI-derived contract.
382
-
383
-
- Both paths are **unconditionally public** in `AuthContextFilter` — they
384
-
cannot be disabled via `public-paths`, because the ACS must reach them
385
-
before it can authorize anything.
386
-
- It is **not** exposed through the external gateway: module IngressRoutes
387
-
only publish API prefixes. The policy content is derived from the OpenAPI
388
-
spec (whose `/v3/api-docs` is public), so no secrets are involved.
389
-
- Scope matching at the edge and in `RequireScopesInterceptor` is **OR**
390
-
(any listed scope suffices). The edge tenant check is presence-only —
391
-
tenant validation stays a module concern via `AuthContext.tenantId()`.
340
+
## Policy Distribution to the Central PDP
341
+
342
+
Services **no longer serve** authorization policies at runtime (the `/.well-known/auth-policy` endpoints have been deleted). Instead, the generated Cerbos policies and route manifests are collected from the build artifacts (`target/cerbos`) and distributed to the Central PDP via a GitOps CI pipeline.
343
+
344
+
1. **Build Time**: The OpenAPI preprocessor emits Cerbos YAML policies (`<module>_api.yaml` and `<DomainResource>.yaml`) and a `routes.yaml` manifest.
345
+
2. **CI Pipeline**: A shared script (`build-cerbos-policies.sh`) aggregates the `target/cerbos` directories from all modules into a centralized policy distribution format.
346
+
3. **Runtime**: The central Cerbos PDP loads these generated policies from a mounted ConfigMap. The Traefik Authproxy loads the `routes.yaml` manifests to understand the path-to-operation mappings.
347
+
4. **Enforcement**: When a request arrives, the Traefik Authproxy queries the central Cerbos PDP for edge reachability (Tier 1). Then, inside your module, the `@Authorize` interceptors from `auth-context-spring-boot-starter` query the central Cerbos PDP for fine-grained domain authorization (Tier 2).
348
+
349
+
This disconnected topology guarantees zero engine footprint inside the Java application, as the policy engine evaluates entirely out-of-process.
Sensitive fields (user, tenant, resolved resource id, raw error) ride the dedicated `io.labs64.authcontext.cedar.detail` logger at DEBUG, off by default. Enable it during the Cedar testing phase, e.g. in `application.yaml`:
469
+
Sensitive fields (user, tenant, resolved resource id, raw error) ride the dedicated `io.labs64.authcontext.cerbos.detail` logger at DEBUG, off by default. Enable it during the Cerbos testing phase, e.g. in `application.yaml`:
524
470
525
471
```yaml
526
472
logging:
527
473
level:
528
-
io.labs64.authcontext.cedar.detail: DEBUG
474
+
io.labs64.authcontext.cerbos.detail: DEBUG
529
475
```
530
476
531
-
The detail line emits `cedar-detail requestId=<id> user=<user> tenant=<tenant> resource=<type>::<id>[ error=<err>]`, shareable with the summary for joining via `requestId`.
477
+
The detail line emits `cerbos-detail requestId=<id> user=<user> tenant=<tenant> resource=<type>::<id>[ error=<err>]`, shareable with the summary for joining via `requestId`.
0 commit comments