Schema Definition & Validation
Relevant source files
The following files were used as context for generating this wiki page:
Schemas govern all data in Infrahub. Every node, attribute, relationship, and constraint must be defined in the schema layer before it exists in the database. Infrahub treats schema definitions as the single source of truth for the entire infrastructure data model.
Sources: dev/constitution.md:29-32, backend/AGENTS.md:12-14
Core Principles
Infrahub enforces schema-driven integrity through the following rules:
- Single Source of Truth: All writes must validate against the active schema for the target branch and point in time.
- Strict Validation: Constraints, unique indexes, and relationship cardinality are enforced before, during, and after migrations.
- Generated Contracts: You must not edit generated files manually; the system regenerates them from schema definitions.
- Branch-Safe Enforcement: Schema validation applies correctly across Infrahub's branching and temporal model.
Sources: dev/constitution.md:34-40, dev/constitution.md:43-45
Schema Generation Pipeline
Infrahub uses a multi-stage offline pipeline to transform Python schema definitions into usable code artifacts for the backend, frontend, and SDK.
This diagram illustrates the flow from source definitions to the final generated types used across the stack.
Sources: dev/knowledge/backend/code-generation.md:7-31
Key Generation Tasks
| Command | Output | Purpose |
|---|---|---|
invoke backend.generate | Pydantic models, Protocols | Generates internal and SDK model families. |
invoke schema.generate-graphqlschema | schema.graphql, openapi.json | Exports the schema for API consumers. |
npm run codegen | TypeScript types | Syncs frontend types with the current schema. |
Sources: dev/knowledge/backend/code-generation.md:33-51
User-Facing Schema Separation
Infrahub separates internal implementation details from user-facing contracts by generating three distinct model families from one source.
Visibility Classification
Every schema field carries a visibility marker that determines its inclusion in specific model families:
- Internal: Backend-only bookkeeping fields. This is the default.
- Read: Fields the user may see in API responses but cannot modify (e.g.,
inherited). - Write: Fields the user is permitted to set via the API or SDK.
Sources: specs/archive/002-user-facing-schema/plan.md:10-15, specs/archive/002-user-facing-schema/PRD-user-facing-schema-separation.md:38-42
Model Families
| Model Family | Location | Visibility Level | Usage |
|---|---|---|---|
| Write Model | Python SDK | write | Used for /api/schema/load and SDK offline validation. |
| Read Model | Python SDK | write + read | Used for /api/schema responses. |
| Internal Model | Backend | write + read + internal | Used for internal domain logic and Neo4j persistence. |
Sources: specs/archive/002-user-facing-schema/plan.md:12-16, specs/archive/002-user-facing-schema/PRD-user-facing-schema-separation.md:65-72
Validation Mechanism
Validation occurs at multiple boundaries to prevent data corruption and provide immediate feedback.
API Boundary Validation
The FastAPI backend utilizes generated Pydantic models to validate incoming requests.
- Model Enforcement: The backend consumes the same SDK-generated Write Model used by clients.
- Hard Rejection: Any submission containing fields not classified as
write(such asinternalor unknown fields) is rejected with a 4xx error. - Enum Propagation: Fields with constrained values (like attribute
kind) publish their full enumeration to the Write Model to prevent invalid string submissions.
Sources: specs/archive/002-user-facing-schema/plan.md:16-19, specs/archive/002-user-facing-schema/PRD-user-facing-schema-separation.md:44-50
SDK Offline Validation
The Python SDK allows users to validate schemas locally without a running server.
- Parity: Because the SDK and Server share the same generated models, a locally-valid schema is guaranteed to pass field and enum validation on the server.
- Independence: The validation logic in the SDK has zero dependencies on the backend package or a Neo4j instance.
Sources: specs/archive/002-user-facing-schema/plan.md:14-16, specs/archive/002-user-facing-schema/PRD-user-facing-schema-separation.md:52-54
Database Layer Integrity
Final integrity is maintained at the query level.
- Parameterization: All Cypher queries use parameter binding (
$param) to prevent injection. - Temporal Constraints: Queries must include branch and temporal filters to ensure data is valid for the requested point in time.
Sources: dev/constitution.md:103-105, dev/constitution.md:47-49
Implementation Components
The diagram shows how internal definitions are transformed into restricted external models based on visibility markers.
Sources: specs/archive/002-user-facing-schema/plan.md:57-70
Validation Checklist
When adding or modifying schema definitions, you must verify the following:
- Classification of each field as
write,read, orinternal. - Idempotent regeneration of backend and SDK models.
- Enrollment of constrained fields into enumerations.
- Passing functional tests for API rejection of non-writable fields.
Sources: specs/archive/002-user-facing-schema/PRD-user-facing-schema-separation.md:102-108, dev/knowledge/backend/code-generation.md:53-63
Schema Definition & Validation ensures that Infrahub remains a reliable source of truth by enforcing strict data contracts from the initial Python definition through to API submission and database persistence.