InfraNotes IAM · v0
Welcome
Select a document from the sidebar to read it.
InfraNotes IAM
The platform Identity and Access Management service for InfraNotes.
SeePRD.md,execution_plan.md, and the
Architecture Decision Records for scope and design
intent. The canonical contracts every downstream service implements
against are underdocs/contracts/.
What this service owns
Per ADR-0001:
- Canonical user and workload identities, subject aliases, session lifecycle
- Authentication (password, magic link, TOTP, passkey/WebAuthn, social, OIDC federation)
- Token issuance, validation metadata (JWKS), revocation, introspection, token exchange
- Tenant lifecycle, membership, role templates, permission overrides, scope bindings, delegated authority
- Workload identity credentials (client secrets, mTLS certs)
- Append-only auth audit events
What stays in domain services: team CRUD and UX, domain resource state,
object-level authorization ("can user X edit invoice Y").
Phase 1 status
Phase 1 (Foundation and Platform Bootstrap) is complete:
- Service skeleton with graceful lifecycle (config, logging, tracing,
metrics, DB pool, Redis client, Kafka publisher) - 19 database migrations applied idempotently to PostgreSQL 18 (native
uuidv7()for UUID v7 primary keys) - System role templates and permission registry seeded
- Signing key bootstrap for local dev (ES256 access + Ed25519 refresh)
-
/health,/ready,/metrics,/.well-known/jwks.json,/.well-known/openid-configuration - Transactional outbox pattern for Kafka reliability
- Helm chart, ArgoCD Application, and Dockerfile
What Phase 1 does not include: login flows, token issuance, tenant
APIs, or the authz API — those are Phase 2 and beyond per
execution_plan.md.
Quick start (local dev)
Prerequisites: Go 1.26+, Docker, and GNU Make.
# Start PostgreSQL, Redis, Kafka, MailHog, and the IAM service in a single stack.
make up
# Tail logs until the service reports "http server listening".
make logs
The compose stack also provisions the contract-defined Kafka topics
idempotently before iam-api starts, so outbox-backed side effects are
available in local end-to-end runs without manual broker setup.
The service listens on:
| Endpoint | Purpose |
|---|---|
| http://localhost:8080/health | Liveness |
| http://localhost:8080/ready | Readiness |
| http://localhost:8080/metrics | Prometheus metrics |
| http://localhost:8080/.well-known/jwks.json | JWKS |
| http://localhost:8080/.well-known/openid-configuration | OIDC discovery |
| http://localhost:8025 | MailHog UI for verification, reset, magic-link, and invitation emails |
To run without Docker (native Go + managed PostgreSQL/Redis):
cp configs/iam.example.yaml configs/iam.yaml
# Edit configs/iam.yaml to point at your DB/Redis/Kafka.
make run
Every configuration key is also available as an IAM_-prefixed environment
variable (dotted keys become underscore-separated — server.http_port
becomes IAM_SERVER_HTTP_PORT).
Development loop
make check # fmt + vet + lint + unit tests
make test-integration # integration tests; requires docker compose up
make docker-build # production image build
Test coverage thresholds are enforced per package by CI. Integration tests
hide behind the integration build tag so go test ./... in an
IDE without Docker running is always fast.
Repository layout
api/openapi/ # OpenAPI 3.1 spec for v1 REST surfaces
proto/iam/v1/ # Protobuf for Authorization, Introspection, Workload services
cmd/iam-api/ # Service entrypoint
configs/ # Sample config YAML
deployments/helm/ # Helm chart (mirrored in infraforge-argocd)
docs/ # ADRs, canonical contracts, migration docs, operations runbooks
internal/ # Go packages (see below)
migrations/ # Ordered SQL migrations embedded into the binary
Key Go packages:
| Package | Role |
|---|---|
internal/config |
Viper-backed config with validation |
internal/observability |
slog logger, Prometheus metrics, OTLP tracing |
internal/database |
pgx v5 pool + migration runner |
internal/cache |
Redis client |
internal/messaging |
CloudEvents envelope + Kafka outbox producer and worker |
internal/crypto/signer |
Signer interface + local-disk implementation |
internal/crypto/keys |
signing_keys table repository + bootstrap + JWK conversion |
internal/handlers/health |
Liveness and readiness handlers |
internal/handlers/wellknown |
JWKS and OIDC discovery handlers |
internal/server |
chi router, middleware chain, HTTP server lifecycle |
Contracts
Every downstream service integrates against the v1 contracts — not against
the IAM binary directly. See docs/contracts/README.md
for the full contract map.
| Contract | Location |
|---|---|
| JWT claims | docs/contracts/jwt-claims.md + schema JSON |
| Gateway headers (Trust Profile B) | docs/contracts/gateway-headers.md |
| gRPC metadata (Trust Profile C) | docs/contracts/grpc-metadata.md |
| Kafka events | docs/contracts/kafka-events.md |
| Error envelope (RFC 7807) | docs/contracts/errors.md |
| OpenAPI | api/openapi/iam.openapi.yaml |
| Protobuf | proto/iam/v1/ |
Architecture Decision Records
All Phase 0 ADRs are accepted and binding inputs to implementation:
| ID | Title | Resolves |
|---|---|---|
| ADR-0001 | Service boundary and ownership | |
| ADR-0002 | Pre-launch clean-break migration | Supersedes PRD §5 |
| ADR-0003 | Trust profiles and identity contract | |
| ADR-0004 | Issuer, signing, key rotation, escrow | PRD §10 Q4 |
| ADR-0005 | Enterprise federation scope for v1 | PRD §10 Q1 |
| ADR-0006 | Mandatory v1 scope-binding types | PRD §10 Q2 |
Commit conventions
Per .claude/rules/Development_Rules.md
§8.3, commits and pull requests MUST NOT reference AI tools. The CI pipeline
rejects Co-authored-by: trailers or "generated by AI" wording in commit
messages.
Support
Platform Engineering owns this service. Open an issue in this repository or
reach the team at platform@infranotes.com.