agentleFS
zalando-incubatorzalando-incubator/agentic-identity-broker/AGENTS.md

agentic-identity-broker

AGENTS.md68 starsChanged 10 days agoMITView on GitHub

Read the relevant source and documents before you decide. Do not infer repository behavior from general knowledge. Paths in this file are relative to the repository root. Read the nearest child AGENTS.md before you change an area. Use the indexes to select relevant sources, not as a requirement to read every document. Maintain shared instructions in the root or nearest child AGENTS.md. Keep tool-specific instruction files limited to scope metadata and routes to those owners. Read routed files before implementation…

The file

Show its rules and text

We split this AGENTS.md into the rules it gives an agent

22 rules. About 0 are common, 10 are distinctive, and 12 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈10

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 12

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Distinctive:

    Use the indexes to select relevant sources, not as a requirement to read every document.

    line 8
  2. Distinctive:

    Keep tool-specific instruction files limited to scope metadata and routes to those owners.

    line 11
  3. Distinctive:

    Read routed files before implementation or review.

    line 12
  4. Distinctive:

    Read the source that governs the change.

    line 16
  5. Very specific:

    Check that this selection matches the task.

    line 67
  6. Very specific:

    Treat .specify/memory/constitution.md as BINDING.

    line 102
  7. Distinctive:

    Domain logic leakage: Put conditional logic beyond input parsing in domain services, not handlers.

    line 114
  8. Distinctive:

    Import rules: Do not let the domain import adapters or app.

    line 136
  9. Very specific:

    Read internal/adapters/AGENTS.md for existing factory and shared-helper composition.

    line 139
  10. Distinctive:

    Read relevant ADRs before implementation.

    line 143
  11. Distinctive:

    Check each file's status and superseding decisions.

    line 144
  12. Distinctive:

    Before the branch merges into main, you can revise that ADR in the same PR, even after acceptance.

    line 147
  13. Very specific:

    After that merge, a change or deviation requires a new Accepted superseding ADR.

    line 149
  14. Very specific:

    Read ARCHITECTURE.md for the full glossary and relationships.

    line 209
  15. Very specific:

    Use just as the command runner.

    line 238
  16. Very specific:

    After Go, test, or infrastructure changes, run just check.

    line 255
  17. Very specific:

    Do not rely only on editor diagnostics.

    line 256
  18. Distinctive:

    Use these rules for all monorepo code (Go, TypeScript, CDK):

    line 260
  19. Very specific:

    Use NNN_description.{up,down}.sql in migrations/.

    line 276
  20. Very specific:

    Keep its first-line -- migrate:no-transaction comment in both directions.

    line 279
  21. Very specific:

    Read tests/integration/AGENTS.md for migration tests.

    line 281
  22. Very specific:

    Read go.mod and each module's manifest for exact versions.

    line 285

≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

Agentic Identity Broker — Agent Context

Read the relevant source and documents before you decide. Do not infer repository behavior from general knowledge.

How to Use This File

Paths in this file are relative to the repository root. Read the nearest child AGENTS.md before you change an area. Use the indexes to select relevant sources, not as a requirement to read every document.

Maintain shared instructions in the root or nearest child AGENTS.md. Keep tool-specific instruction files limited to scope metadata and routes to those owners. Read routed files before implementation or review. A route is not a substitute for its instructions.

Docs Index (Retrieval Targets)

Read the source that governs the change. The summaries here do not replace the constitution, accepted ADRs, or API contracts.

Architecture & Decisions

ARCHITECTURE.md | Source of truth for system design adrs/ | Architecture decisions and status (see the ADR index) .specify/memory/constitution.md | Binding constitution — 15 principles governing all work CONTRIBUTING.md | Setup, contribution process, and verification requirements docs/resources/assurance-case.md | Threat model, trust boundaries, and security evidence

Coding Standards

coding-standards/LOGGING.md | Structured logging: plumbing, record shape, levels, principals, permitted data. Read before you add or change a log call. coding-standards/OPENTELEMETRY.md | Traces and metrics: plumbing, span names and status, attribute keys, instruments, permitted data. Read before you add or change a span or metric.

Section-Specific Agent Context

internal/AGENTS.md | Backend hexagonal architecture, builder pattern, testing conventions internal/domain/AGENTS.md | Domain layer rules, zero-infra imports, data models, error types internal/domain/id/AGENTS.md | Strongly typed entity IDs, code generation, type catalogue internal/ports/AGENTS.md | Port interface catalogue, ISP rules, error conventions internal/adapters/AGENTS.md | Adapter map, cross-adapter ban, storage/encryption/HTTP details internal/extproc/AGENTS.md | Standalone ExtProc token exchange service, config, architecture web/AGENTS.md | React SPA, design system, API client, testing infra/AGENTS.md | AWS CDK encryption stack, IRSA, environment parameterization tests/AGENTS.md | E2E + integration test suite overview tests/e2e/AGENTS.md | Ginkgo E2E rules, fixtures, dual-server pattern, anti-patterns tests/e2e/frontend/AGENTS.md | Playwright browser tests, page objects tests/integration/AGENTS.md | Self-contained and infrastructure-backed integration test guidance

Runtime Entry Points

cmd/agentic-identity-broker/ | Broker CLI, configuration, and dual-server startup cmd/extproc-token-exchange/ | ExtProc CLI, telemetry bridge, and gRPC startup

API Contracts

api/enduser/openapi.yaml | End-user API: consent, OAuth2, sessions, and approvals api/admin/openapi.yaml | Admin API: agents, services, resources, permission sets, and session sweep

Specs (Feature Requirements)

specs/NNN-<name>/spec.md | Feature requirements + acceptance scenarios specs/NNN-<name>/plan.md | Implementation approach specs/NNN-<name>/tasks.md | Trackable task list .specify/templates/overrides/spec-template.md | Spec template: required sections, including concrete example journeys (Principle XIV) .specify/examples/specification-by-example.md | Worked example journey and Wireloom render command (Principle XIV) .specify/templates/overrides/tasks-template.md | Tasks template: mandatory Phase 2 design and Phase N compliance tasks

For feature work, read its spec.md, plan.md, and tasks.md before implementation. Spec Kit selects SPECIFY_FEATURE_DIRECTORY first, then .specify/feature.json. Check that this selection matches the task. Do not infer the feature from the branch name alone. .specify/scripts/bash/common.sh defines this selection order.

Encryption Deep Reference

.agents/skills/aws-crypto-go/SKILL.md | AWS Encryption SDK Go — patterns, rules .agents/skills/aws-crypto-go/reference.md | API reference .agents/skills/aws-crypto-go/examples.md | Code examples

Design System (Frontend)

web/src/design-system/docs/INDEX.md | Complete design system documentation index web/src/design-system/docs/COMMON_MISTAKES.md | Read before you work on a styled component web/src/design-system/docs/DECISION_TREES.md | Which component to use when

Operations & Guides

docs/ENCRYPTION_INTEGRATION_GUIDE.md | Encryption integration guide docs/STORAGE_EXTENSION_GUIDE.md | Adding new storage entities docs/STORAGE_TROUBLESHOOTING.md | Storage debugging docs/configuration.md | Configuration reference docs/deployment/ | Deployment guides (Kubernetes, IRSA) docs/operations/ | Operations runbooks examples/config/ | Example configuration files charts/agentic-identity-broker/ | Helm deployment contract migrations/ | PostgreSQL schema migrations mocks/ | Standalone test services and OAuth2 clients configs/ | Development, test, production, and container configuration scripts/ | Development helpers and deployment checks justfile | Maintained commands and their dependencies .github/workflows/ | CI, security, coverage, and release gates assets/docusaurus/ | Documentation-site source and build configuration

Constitution (Binding) — 15 Principles

Treat .specify/memory/constitution.md as BINDING. Apply these principles:

  1. Security-First — Fail closed. Do not bypass security controls. Only accepted ADR 031 permits unsigned subjects, with its full controls. This exception applies only to explicit unverified-subject rules in local-mode impersonation. Client assertions, actor tokens, and signed subjects still require signature verification.
  2. Accepted ADRs are Binding — Only ADRs with status "Accepted" are binding. Use ARCHITECTURE.md as the source of truth. Follow Principle II for same-PR ADR acceptance and revisions. A merged Accepted ADR requires an Accepted superseding ADR for deviations.
  3. Library-First Security — Do not use custom crypto. Use Go crypto/*, golang.org/x/crypto, or AWS Encryption SDK.
  4. OpenAPI Transparency — Define APIs in api/{enduser,admin}/openapi.yaml before implementation.
  5. Domain-Driven Design — Enforce ubiquitous language. Add new concepts to the ARCHITECTURE.md glossary.
  6. Hexagonal Architecture — Domain services depend on ports, not adapters. Adapters implement ports. Prevent these violations:
    • Port bypass: Route handlers through domain services to ports. Do not route a handler to a port directly.
    • Anemic domain: Make services enforce invariants. Do not only proxy port calls.
    • Domain logic leakage: Put conditional logic beyond input parsing in domain services, not handlers.
    • Domain packaging: Make each new domain/X/ a genuinely independent bounded context.
  7. Configuration-Driven — Use internal/ports/config.go for broker configuration. ExtProc has its own schema under accepted ADR 011. Update configuration documentation and examples with each parameter change. Update Helm values and templates only for workloads that the chart deploys.
  8. TDD — Use red-green-refactor. Write tests first. Make each test fail before implementation.
  9. Persistence Consistency — Define ISP repos in internal/ports/storage.go. Use sqlx for PostgreSQL. Provide both in-memory and postgres adapters.
  10. API-First — Design APIs before implementation. Get stakeholder agreement before changes.
  11. Design System Compliance — Use shared semantic tokens and WCAG 2.1 AA. Check light and dark themes. Keep brand assets in the repository. Read the current visual direction in web/src/design-system/docs/DESIGN_PRINCIPLES.md. A change to that direction requires an ADR.
  12. DI via Builder — Put broker dependency wiring in internal/app/builder.go. Do not instantiate services in routing.
  13. E2E Acceptance Tests — Use a 1:1 specification-to-test mapping in tests/e2e/. Test a complete user journey. Do not test one endpoint segment.
  14. Specification by Example — In each spec, add concrete user journeys and link them to the Given/When/Then scenarios. Where applicable, show configuration, RFC-style HTTP exchanges, Wireloom wireframes, and decoded JWT claims.
  15. Binding Coding Standards — Follow every applicable standard in coding-standards/, including its review checklist and required tests, contracts, and registry entries. See Principle XV for scoped exceptions.

Monorepo Structure

SectionTechnologyAGENTS.md
internal/Go — domain services, ports, adapters, and app wiringinternal/AGENTS.md
web/React + TypeScript + Vite + Tailwindweb/AGENTS.md
infra/cdk/AWS CDK (Go) — KMS, DynamoDB, IAMinfra/AGENTS.md
tests/Ginkgo/Gomega (e2e), Go testing (integration)tests/AGENTS.md
internal/extproc/Standalone gRPC ExtProc serviceinternal/extproc/AGENTS.md

Import rules: Do not let the domain import adapters or app. Define contracts in ports. Let driven adapters import ports and domain. HTTP routing receives handlers from app. It can use routing middleware and configuration. Do not couple independent adapter subsystems. Read internal/adapters/AGENTS.md for existing factory and shared-helper composition.

ADR Decision Index

Read relevant ADRs before implementation. Only accepted decisions are binding. Check each file's status and superseding decisions. A proposal does not become binding because its code exists. ADR numbers are not unique in this repository. Use the full filename. You can mark an ADR introduced on this branch as Accepted in the same PR. Before the branch merges into main, you can revise that ADR in the same PR, even after acceptance. The final ADR and code MUST agree before merge. After that merge, a change or deviation requires a new Accepted superseding ADR. See Principle II in .specify/memory/constitution.md.

ADRFileDecision
002adrs/002-configuration-libraries.mdViper + Cobra + godotenv config
003adrs/003-chi-framework.mdchi v5 HTTP router
004adrs/004-dual-server-isolation.mderrgroup dual-server :8000/:14000
004adrs/004-storage-layer-architecture.mdHexagonal storage, ISP repos, sqlx
005adrs/005-spa-serving-pattern.mdSPA serving, with mount and build paths superseded by ADR 035
006adrs/006-frontend-stack.mdReact + Vite + Tailwind + Vitest
007adrs/007-e2e-testing-with-ginkgo.mdGinkgo v2 BDD E2E tests
008adrs/008-encryption-context-optimization.mdSingle-subject context: service_id or kid, as defined by its amendment
008adrs/008-token-exchange-jwks-adapter-pattern.mdJWKS adapter with jwx jwk.Cache
009adrs/009-cel-for-authorization-policies.mdcel-go for authorization + JWT claims
009adrs/009-envelope-encryption-design.mdThree-layer envelope: KEK→BranchKey→DEK
009adrs/009-separate-migration-docker-image.mdSeparate migration Docker image
010adrs/010-cdk-encryption-infrastructure.mdAWS CDK for encryption IaC
011adrs/011-extproc-standalone-binary.mdExtProc as standalone binary
011adrs/011-opentelemetry-provider-pattern.mdOpenTelemetry provider pattern
012adrs/012-encryption-layer-separation.mdEncryption layer separation
012adrs/012-extproc-in-memory-token-cache.mdExtProc in-memory token cache
013adrs/013-strongly-typed-entity-ids.mdTyped entity IDs (XxxID) in domain/id/
014adrs/014-long-poll-listen-notify.mdLong-poll approval sync via PostgreSQL LISTEN/NOTIFY
014adrs/014-oauth2-server-mode.mdOAuth2 authorization server mode
015adrs/015-cimd-fetcher-architecture.mdCIMD fetcher architecture
016adrs/016-authorization-session-anti-spoofing.mdAuthorization session anti-spoofing
017adrs/017-optional-agent-client-id.mdOptional/nullable Agent client_id
018adrs/018-approval-endpoint-auth-boundaries.mdEndpoint-specific approval authentication boundaries
027adrs/027-extproc-telemetry-shared-dependency.mdExtProc telemetry shared dependency
028adrs/028-opa-extproc-authorization.mdOPA authorization in ExtProc via embedded SDK
029adrs/029-token-exchange-client-assertion-trust-anchor.mdProposed: dedicated client-assertion trust anchor
030adrs/030-normalize-protected-resources.mdNormalized, globally unique protected-resource child records
030adrs/030-vendor-neutral-oidc-trust.mdVendor-neutral CDK OIDC trust configuration
031adrs/031-unverified-subject-unsigned-jwt.mdBounded unsigned-subject exception for local impersonation
032adrs/032-impersonation-requires-user-delegation.mdUser delegation required for OAuth2 impersonation
033adrs/033-request-security-context-propagation.mdProposed: request security context and audit identity
034adrs/034-audience-absent-impersonation-credentials.mdExplicit absent-audience policy for signed impersonation credentials
035adrs/035-root-mounted-spa.mdRoot-mounted SPA. /consent is not mounted
035adrs/035-shared-tool-pattern-matching.mdApproval pattern grammar shared with ExtProc
036adrs/036-extproc-approval-cache-and-gate.mdExtProc approval cache, sync, and request gate
036adrs/036-extproc-metadata-token-exchange-input.mdToken-exchange input from gateway metadata
036adrs/036-public-client-token-endpoint-auth.mdExplicit public-client authentication, extended by CIMD ADR 037
037adrs/037-cimd-client-authentication-key-domain.mdSeparate CIMD authentication keys and public JWK sets
037adrs/037-consent-selection-oauth-redirect-state.mdProposed: consent selection across OAuth redirects
038adrs/038-proactive-token-refresh.mdBackground token refresh and operator-driven synchronous session sweep
039adrs/039-concurrent-session-expiry-index.mdNamed non-atomic migration 037 exception with direct CLI and manual recovery
040adrs/040-trust-anchor-local-key-sets.mdInline and file-based key sets for trust anchors (trust directory, re-read, health)
040adrs/040-protected-resource-discovery-and-dcr.mdProtected-resource discovery and DCR client selection
041adrs/041-oauth2-client-secret-file-overrides.mdExplicit stored/filesystem credentials and established client identity
042adrs/042-agent-allowlisted-private-use-redirect-uris.mdPrivate-use (custom-scheme) redirect URIs only when the Agent allowlists them; CIMD also needs the document entry
043adrs/043-inbound-cimd-private-key-jwt.mdInbound CIMD client assertion validation, replay protection, and refresh authentication strength
044adrs/044-service-specific-session-recovery-url.mdRecoverable session error_uri starts resolved service OAuth2 with encoded same-origin /sessions return URI
044adrs/044-client-registration-independent-of-authentication.mdIndependent static/CIMD registration and token-endpoint method, keyless CIMD public clients, guarded migrations
045adrs/045-agent-subject-impersonation.mdSigned self-agent issuance without user delegation; target-derived subject; configurable third-party detection
046adrs/046-observed-refresh-token-rejection.mdObserved provider refresh rejection replaces predicted refresh expiry; requires_reauthentication; no schema change
047adrs/047-unique-agent-external-id-reconcile.mdUnique Agent external IDs, collection PUT reconciliation, safe migration 047, and Admin API 3.0.0

Domain Glossary

Read ARCHITECTURE.md for the full glossary and relationships.

TermDefinition
AgentAI agent with optional client ID and client metadata document URLs.
External IDOptional nonempty, globally unique Agent governance identifier, matched literally; collection PUT reconciles by it without changing UUID identity.
Agent ReconciliationReconcile is the canonical term for applying an Agent definition by External ID while preserving UUID identity; upsert and create-or-update are aliases for this operation. The ReconcileUnchanged outcome means no-op/replay: no write or mutation audit, with stored timestamps preserved.
Subject Categoryagent only for a raw sub exactly equal to the audience-selected target UUID that is signed and verified, or unverified with a predicate binding subject_token.sub; another registered agent's UUID is a rejected cross-agent request; otherwise human.
Allowed Subject CategoriesPer-rule eligibility list; omission means [human]. Classification is independent of eligibility.
Agent-Subject TokenImpersonated broker token from self-agent issuance: reserved sub == agent_id == target UUID, no category claim. Detected by the boolean CEL detector agent_subject_expression (a replacement must reference subject_token.sub); rejected by third-party exchange and subject-token approval authentication before human-state access.
ThirdpartyOAuth2ServiceExternal OAuth2 provider with credentials and scopes.
UserGrantUser delegation of permission sets to an agent. One per user-agent pair.
AuthorizationSessionClaimsJWE-sealed authorization context with a 10-minute TTL.
UserSessionAuthenticated OAuth2 session with encrypted tokens.
PrincipalAuthenticated user identity from the configured pre-authentication source.
SecretValue object with exclusive plaintext, encrypted, or absent state.
ServiceRequirementAgent requirement for a mandatory or optional service.
BranchKeyDynamoDB-cached key between a KMS KEK and an operation DEK.
EncryptionContextAAD with exactly one subject key: service_id or kid. Never store secrets.
ResourceURINormalized protected-resource URI for RFC 8693 token exchange.
CEL ExpressionPolicy for privileged-client authorization and JWT claim extraction.
ToolApprovalHuman-in-the-loop authorization for an agent tool call with pending, approved, or denied status.
Key Set SourceOrigin of one trust anchor's public keys: remote (jwks_uri, discovery, or ADR 029 reuse), inline (jwks), or file (jwks_file). One per trust anchor. Not the JWKS publisher's KeySource.
Local Key SetValidated JWK Set from an inline or file Key Set Source: public asymmetric keys only, unique kid, at most 1 MiB. Never published.
Trust DirectoryDirectory security.trust_material_dir, the only place the broker reads key-set files, opened through os.Root.
Refresh RejectionObserved terminal provider invalid_grant for a stored refresh token (UserSession.RefreshRejectedAt). The broker never predicts refresh-token expiry.

Development Workflow

Use just as the command runner. Run just --list for the full listing.

CommandPurpose
just checkNon-mutating format, vet, and lint checks
just fmtApply Go formatting changes
just buildBuild Go binary → ./bin/agentic-identity-broker
just testFast Go/package tests (no E2E or integration suites)
just verifyFull gate: static checks, security scans, tests, integration, then E2E
just build-allBackend + frontend build
just test-e2eAll backend, ExtProc, and frontend E2E suites
just test-integrationDefault self-contained integration suites
just test-integration-infraInfra-backed integration suites (Docker/Podman required)
just test-integration-allBoth integration layers
just cdk-testCDK unit tests
just render-wireframes <spec.md>Render Wireloom wireframes in a spec to SVG (after just install-tools)

After Go, test, or infrastructure changes, run just check. Then run the smallest matching test command. Do not rely only on editor diagnostics. Before a pull request, run the full gate from CONTRIBUTING.md.

Code Style

Use these rules for all monorepo code (Go, TypeScript, CDK):

  • Minimize comments — Write a comment only for context that code alone cannot convey.
  • Never restate code — Do not write comments that add no information.
  • No debug artifacts — Do not leave debug logging, commented-out code, TODO stubs, or future-implementation references.
  • Match surrounding style — Keep naming, error handling, and file structure consistent with adjacent code.
  • Explicit over clever — Make intent clear without tracing abstractions.
  • Extend, do not duplicate — Use an existing mechanism (for example, JWE for ephemeral state). Do not introduce a competing one.
  • Explicit SQL columns — List required result columns in SQL queries, including queries in migrations and tests. Do not use SELECT *, table.*, or RETURNING *. Wildcard projections hide data dependencies and couple readers to schema changes. COUNT(*) and EXISTS (SELECT 1 ...) are permitted.
  • Structured logging — Follow coding-standards/LOGGING.md. Log principals only as id.Principal. Never log credentials.
  • OpenTelemetry — Follow coding-standards/OPENTELEMETRY.md. Use constant span names. Set principals on spans only through id.Principal.SpanAttribute, and add none until #356 provides it. Never put a principal in a metric or a credential in any signal.
  • No test-only production APIs — Put test helpers in _test.go or tests/. Assert through production APIs.

Database Migrations

Use NNN_description.{up,down}.sql in migrations/. Test both directions against PostgreSQL with the production migrations. Each migration must be atomic, as required by Constitution Principle IX. Non-atomic migrations require an accepted ADR exception. adrs/039-concurrent-session-expiry-index.md permits concurrent index creation and removal only for migration 037. Keep its first-line -- migrate:no-transaction comment in both directions. The comment is informational, not enforced by the migration runners. Migration 030 is historical, not an approved template for new non-atomic migrations. Read tests/integration/AGENTS.md for migration tests.

Active Technologies

Read go.mod and each module's manifest for exact versions. The stack uses chi v5, sqlx, pgx v5, Ginkgo/Gomega, Viper/Cobra, CVA, OpenTelemetry (otelhttp, otelslog), and Envoy ExtProc. PostgreSQL is the production store. In-memory storage is for development and tests.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.