InfraForge Docs

InfraNotes IAM · v0

Welcome

Select a document from the sidebar to read it.

InfraNotes IAM

The platform Identity and Access Management service for InfraNotes.
See PRD.md, execution_plan.md, and the
Architecture Decision Records for scope and design
intent. The canonical contracts every downstream service implements
against are under docs/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.