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
| Backend | Connection string | Use 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.
- Python
- TypeScript
- Go
- Java
- C#
service = ANIPService(
service_id="my-service",
capabilities=[...],
storage="memory", # or omit — memory is the default
authenticate=...,
)
const service = createANIPService({
serviceId: "my-service",
capabilities: [...],
storage: { type: "memory" }, // default
authenticate: ...,
});
svc, _ := service.New(service.Config{
ServiceID: "my-service",
Capabilities: capabilities,
Storage: "memory", // default
Authenticate: authenticate,
})
new ANIPService(new ServiceConfig()
.setServiceId("my-service")
.setCapabilities(capabilities)
.setStorage("memory") // default
.setAuthenticate(authenticate));
var service = new AnipService(new ServiceConfig {
ServiceId = "my-service",
Capabilities = capabilities,
Storage = "memory", // default
Authenticate = authenticate,
});
SQLite (single-instance production)
Persistent local storage. Good for single-process deployments.
- Python
- TypeScript
- Go
- Java
- C#
service = ANIPService(
service_id="my-service",
capabilities=[...],
storage="sqlite:///anip.db",
authenticate=...,
)
const service = createANIPService({
serviceId: "my-service",
capabilities: [...],
storage: { type: "sqlite", path: "anip.db" },
authenticate: ...,
});
svc, _ := service.New(service.Config{
ServiceID: "my-service",
Capabilities: capabilities,
Storage: "sqlite:///anip.db",
Authenticate: authenticate,
})
new ANIPService(new ServiceConfig()
.setServiceId("my-service")
.setCapabilities(capabilities)
.setStorage("sqlite:///anip.db")
.setAuthenticate(authenticate));
var service = new AnipService(new ServiceConfig {
ServiceId = "my-service",
Capabilities = capabilities,
Storage = "sqlite:///anip.db",
Authenticate = authenticate,
});
PostgreSQL (cluster production)
Shared storage for multi-replica deployments. Required for horizontal scaling.
- Python
- TypeScript
- Go
- Java
- C#
service = ANIPService(
service_id="my-service",
capabilities=[...],
storage="postgres://user:pass@host:5432/anip",
authenticate=...,
)
const service = createANIPService({
serviceId: "my-service",
capabilities: [...],
storage: { type: "postgres", connectionString: "postgres://user:pass@host:5432/anip" },
authenticate: ...,
});
svc, _ := service.New(service.Config{
ServiceID: "my-service",
Capabilities: capabilities,
Storage: "postgres://user:pass@host:5432/anip",
Authenticate: authenticate,
})
new ANIPService(new ServiceConfig()
.setServiceId("my-service")
.setCapabilities(capabilities)
.setStorage("postgres://user:pass@host:5432/anip")
.setAuthenticate(authenticate));
var service = new AnipService(new ServiceConfig {
ServiceId = "my-service",
Capabilities = capabilities,
Storage = "postgres://user:pass@host:5432/anip",
Authenticate = 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.):
- Python
- TypeScript
- Go
- Java
- C#
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:
emailclaim →human:{email}subclaim →oidc:{sub}
API keys continue to work alongside OIDC tokens.
OIDC_ISSUER_URL=https://keycloak.example.com/realms/anip
OIDC_AUDIENCE=my-service
The TypeScript runtime reads these environment variables and configures OIDC validation automatically. The authenticate callback receives OIDC tokens alongside API keys.
OIDC_ISSUER_URL=https://keycloak.example.com/realms/anip
OIDC_AUDIENCE=my-service
The Go runtime reads these environment variables and validates OIDC tokens using the issuer's JWKS endpoint.
OIDC_ISSUER_URL=https://keycloak.example.com/realms/anip
OIDC_AUDIENCE=my-service
The Java runtime configures OIDC validation from environment variables. Works with both Spring Boot and Quarkus adapters.
OIDC_ISSUER_URL=https://keycloak.example.com/realms/anip
OIDC_AUDIENCE=my-service
The C# runtime reads OIDC configuration from environment variables and integrates with ASP.NET Core's authentication pipeline.
Trust level
The trust setting controls the cryptographic trust posture of the service:
| Level | What it means | When to use |
|---|---|---|
"declarative" | No signing — capabilities are declared but not cryptographically verified | Development, testing |
"signed" | Manifest and tokens are signed with the service's key pair, JWKS published | Production |
"anchored" | Audit checkpoints are anchored to external trust sources | Compliance, regulated environments |
- Python
- TypeScript
- Go
- Java
- C#
service = ANIPService(
service_id="my-service",
capabilities=[...],
trust="signed",
key_path="keys/", # directory for key storage
authenticate=...,
)
const service = createANIPService({
serviceId: "my-service",
capabilities: [...],
trust: "signed",
keyPath: "keys/",
authenticate: ...,
});
svc, _ := service.New(service.Config{
ServiceID: "my-service",
Capabilities: capabilities,
Trust: "signed",
KeyPath: "keys/",
Authenticate: authenticate,
})
new ANIPService(new ServiceConfig()
.setServiceId("my-service")
.setCapabilities(capabilities)
.setTrust("signed")
.setKeyPath("keys/")
.setAuthenticate(authenticate));
var service = new AnipService(new ServiceConfig {
ServiceId = "my-service",
Capabilities = capabilities,
Trust = "signed",
KeyPath = "keys/",
Authenticate = 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:
- Python
- TypeScript
- Go
- Java
- C#
from anip_server import CheckpointPolicy
service = ANIPService(
service_id="my-service",
capabilities=[...],
checkpoint_policy=CheckpointPolicy(interval_seconds=60),
authenticate=...,
)
const service = createANIPService({
serviceId: "my-service",
capabilities: [...],
checkpointPolicy: { intervalSeconds: 60 },
authenticate: ...,
});
svc, _ := service.New(service.Config{
ServiceID: "my-service",
Capabilities: capabilities,
CheckpointPolicy: service.CheckpointPolicy{IntervalSeconds: 60},
Authenticate: authenticate,
})
new ANIPService(new ServiceConfig()
.setServiceId("my-service")
.setCapabilities(capabilities)
.setCheckpointPolicy(new CheckpointPolicy().setIntervalSeconds(60))
.setAuthenticate(authenticate));
var service = new AnipService(new ServiceConfig {
ServiceId = "my-service",
Capabilities = capabilities,
CheckpointPolicy = new CheckpointPolicy { IntervalSeconds = 60 },
Authenticate = authenticate,
});
Next steps
- Quickstart — Build and run a service
- Authentication — Deep dive into the auth model
- Deployment guide — Cluster deployment with PostgreSQL