Skip to main content

Configuration

Every ANIP service is configured through a service config object. This page covers the key configuration options: storage, authentication, trust level, and runtime behavior.

Storage

ANIP manages its own storage for audit logs, delegation tokens, checkpoints, and internal coordination state. You configure it with a connection string — the runtime handles schema creation, migrations, and all database operations internally.

Supported backends

BackendConnection stringUse case
In-memory"memory" or ":memory:"Development, testing
SQLite"sqlite:///path/to/db"Single-instance production
PostgreSQL"postgres://user:pass@host:5432/db"Multi-replica production

These are the three backends ANIP supports today. Other databases (MySQL, MongoDB, etc.) are not currently supported.

ANIP storage is separate from your application database

ANIP's storage is for protocol state only — audit logs, tokens, checkpoints, and leases. It does not store your application data. Your capability handlers can use any database, ORM, or data layer you want (SQLAlchemy, Prisma, GORM, Hibernate, Entity Framework — anything). The ANIP storage configuration only affects the protocol runtime's own state.

┌─────────────────────────────────────────────┐
│ Your Application │
│ │
│ Capability handlers ──→ Your database │
│ (any ORM, any DB) (MySQL, Mongo, │
│ Redis, etc.) │
│ │
│ ANIP runtime ──────────→ ANIP storage │
│ (audit, tokens, (SQLite or │
│ checkpoints) PostgreSQL) │
└─────────────────────────────────────────────┘

In-memory (development)

No persistence — data is lost when the process exits. Good for tests and development.

service = ANIPService(
service_id="my-service",
capabilities=[...],
storage="memory", # or omit — memory is the default
authenticate=...,
)

SQLite (single-instance production)

Persistent local storage. Good for single-process deployments.

service = ANIPService(
service_id="my-service",
capabilities=[...],
storage="sqlite:///anip.db",
authenticate=...,
)

PostgreSQL (cluster production)

Shared storage for multi-replica deployments. Required for horizontal scaling.

service = ANIPService(
service_id="my-service",
capabilities=[...],
storage="postgres://user:pass@host:5432/anip",
authenticate=...,
)

The runtime creates all required tables automatically on first connection — just point it at an empty PostgreSQL database. With PostgreSQL, multiple replicas can run behind a load balancer with automatic coordination. See Horizontal Scaling for details.

Authentication

ANIP supports multiple authentication methods that can be used simultaneously.

API keys

The simplest path — map bearer strings to principal identities. See Authentication for examples in all languages.

OIDC / OAuth2

Validate external JWTs from any OIDC-compliant identity provider (Keycloak, Auth0, Okta, Azure AD, etc.):

Set environment variables:

OIDC_ISSUER_URL=https://keycloak.example.com/realms/anip
OIDC_AUDIENCE=my-service # defaults to service_id
# OIDC_JWKS_URL=... # optional override

The service auto-discovers the OIDC configuration from the issuer URL, validates incoming JWTs, and maps claims to ANIP principals:

  • email claim → human:{email}
  • sub claim → oidc:{sub}

API keys continue to work alongside OIDC tokens.

Trust level

The trust setting controls the cryptographic trust posture of the service:

LevelWhat it meansWhen to use
"declarative"No signing — capabilities are declared but not cryptographically verifiedDevelopment, testing
"signed"Manifest and tokens are signed with the service's key pair, JWKS publishedProduction
"anchored"Audit checkpoints are anchored to external trust sourcesCompliance, regulated environments
service = ANIPService(
service_id="my-service",
capabilities=[...],
trust="signed",
key_path="keys/", # directory for key storage
authenticate=...,
)

When trust is "signed" or higher, the runtime generates an Ed25519 key pair on first run (stored in key_path) and uses it to sign manifests, delegation tokens, and checkpoints.

Checkpoint policy

Control how often Merkle checkpoints are generated over the audit log:

from anip_server import CheckpointPolicy

service = ANIPService(
service_id="my-service",
capabilities=[...],
checkpoint_policy=CheckpointPolicy(interval_seconds=60),
authenticate=...,
)

Next steps