ibexharness
DocsBlogReleasesRoadmap
GitHub
ibexharness

Documentation

Architecture Decision RecordsADR-0002: Repository foundation bootstrapADR-0003: Branch protection and merge policyADR-0004: Protobuf and code generation policyADR-0005: Postgres migration strategyADR-0006: Auth protobuf contract (`ibex.auth.v1`)ADR-0007: Auth token validation implementationADR-0008: Security scanning and CI quality gatesADR-0009: Permission bitmap layoutADR-0010: Cryptography policyADR-0011: Proxy auth gRPC client and middlewareADR-0012: Proxy request normalization (OpenAI chat)ADR-0013: Proxy input validation and stable error envelopeADR-0014: Core domain migration sequencingADR-0015: Proxy rate limit skeleton (Phase 1)ADR-0016: Proxy agent identity verification (Phase 1)ADR-0017: Request ID and trace context strategy (Phase 1)ADR-0018: Graceful shutdown contract (Phase 1)ADR-0019: OpenTelemetry provider configuration (Phase 1)ADR-0020: Shared package boundaries — `packages/config` and `packages/apierror`ADR-0021: Prometheus Metric Catalog (Phase 1)ADR-0022: Health check contract (Phase 1)ADR-0023: Docs site architecture (Phase 1.5)
ADRs›ADR-0014: Core domain migration sequencing
ADRs

ADR-0014: Core domain migration sequencing

Architecture decision record 0014.

ADR-0014: Core domain migration sequencing

Status

Accepted

Context

Phase 1 requires tenant isolation and fail-closed identity verification on the auth/proxy path. The database already contains:

  • ibex_core.organizations
  • ibex_core.tokens (with nullable user_id, agent_id, and revoked_by)

At the time of milestone 1.1.1, users and agents were intentionally deferred so the initial migration could be minimal and unblock the token/permission plane.

That deferral left two security-critical gaps tracked in Phase 1 milestones:

  • Token FK integrity (S-2): tokens.user_id / agent_id / revoked_by had no foreign keys, so revocation and tenant-scoping could not rely on referential integrity. Resolved in M1.1.7.
  • Agent identity (S-1): The proxy accepted X-IBEX-Agent-ID as a UUID without validating org ownership. The fix is M1.2.5, which depends on ibex_core.agents from M1.1.7.

Decision

  1. Introduce ibex_core.users and ibex_core.agents in milestone M1.1.7 as the Phase-1 subset of the domain schema.
  2. Add foreign keys for ibex_core.tokens in milestone M1.1.7 using the Postgres pattern:
    • ADD CONSTRAINT ... NOT VALID
    • VALIDATE CONSTRAINT in a follow-up statement
  3. Keep this milestone narrowly scoped: only the Phase-1 subset needed for ValidateAgent and token FK integrity. Full domain columns are deferred to later phases.

Why NOT VALID + VALIDATE CONSTRAINT

Adding foreign keys to an existing large table can require scanning and acquiring locks. Using NOT VALID allows the constraint to be added without immediate validation of existing rows. Since Phase 1’s baseline data uses NULL values in these FK columns until the new tables exist, this keeps make db-migrate fast while still guaranteeing enforcement after VALIDATE CONSTRAINT.

Consequences

  • Referential integrity for token-scoped identities is enforced at the database layer once M1.1.7 is applied.
  • Proxy/validator logic can rely on tenant-scoped identity lookups without existence leakage.
  • Migration down in development should be treated as a rollback convenience only; production rollback follows the standard migration strategy documented in ADR-0005.

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0013: Proxy input validation and stable error envelopeNextADR-0015: Proxy rate limit skeleton (Phase 1)

On this page

  • Status
  • Context
  • Decision
  • Why NOT VALID + VALIDATE CONSTRAINT
  • Consequences
0%