Security Architecture
AGLedger produces one object: a signed record spanning the full lifecycle of a piece of automated work - the intent and authority at the start, the delegation handoffs in the middle, the result at the end, and the verdict when the work is gated. This whitepaper is written for security teams, compliance officers, and procurement reviewers: how the record is signed, what the signature covers, where the trust boundaries fall, and how a third party confirms it offline. Every claim below is checkable against the published keys, with no AGLedger account and no network call.
One signing key per Server instance. A single instance vault key (VAULT_SIGNING_KEY, Ed25519 by default) signs every entry in that Server’s chain. There is no per-principal and no per-agent key. The signature is the notary’s.
Attribution lives inside the signature. The accountable principal (principal_agent_id) and the acting credential are named inside the signed payload, so the signature covers the attribution. This is notary-attested, tamper-evident attribution - not principal-held non-repudiation: the principal does not sign, and we do not represent that it did.
Self-hosted by design. AGLedger runs in your infrastructure. No data leaves it unless you explicitly enable federation, and even then only signed bytes cross the boundary.
Zero content inspection. AGLedger records accountability metadata - who notarized what, who delivered, who accepted. It never inspects, stores, judges, or processes your business data, prompts, or model outputs.
Standards-based. COSE_Sign1 (RFC 9052, tag 18) over an in-toto v1 Statement payload, deterministic CBOR (RFC 8949 §4.2.1), Ed25519 + SHA-256, CWT Claims (RFC 8392 / RFC 9597), HMAC-SHA256, RFC 9421 HTTP Message Signatures, RFC 8785 JSON canonicalization, RFC 9457 problem details. No bespoke primitives.
1. The signed record - what the signature covers
The agent reports with its key; the notary signs what it reported. The agent (or any caller) makes the API call that records a stage of the work. The Server - not the caller - assembles the entry, encodes it, and signs it with the instance vault key. The authority being recorded is the principal’s; the signature is the notary’s.
Because the attribution rides inside the signed payload, an entry cannot be re-pointed at a different principal without invalidating the signature. The protected header carries the actor identity as a CWT private claim ({ key_id, role, owner_id }); any delegation context rides in the in-toto Statement predicate as on_behalf_of. Both are covered by the Ed25519 signature. To the auditor, the claim is exact: the chain proves what was reported, signed, and recorded, and that the attribution has not been altered since.
Agents are not required to hold signing keys. The default path needs no client-side cryptography from the agent: it authenticates and reports, and the notary signs. An optional per-request attestation path (X-Agent-Signature / X-Agent-Signature-Content-Hash), a no-op by default, lets a cert-bound caller co-sign its own request; the co-signature is carried into the envelope as predicate.on_behalf_of.agent_signature and honored only when the caller authenticated with an ephemeral cert (§7).
2. Deployment model and trust boundaries
AGLedger is software you deploy, not a service you send data to. One role: Server. Every install is the same binary. A Server is a sovereign domain: its own database, auth, agents, contracts, signing key, and chain. Federation participation is a per-record / per-contract / global flag, not a deployment mode.
We do: record accountability metadata in your infrastructure. We do not: host your data, proxy your traffic, judge your work, or require outbound connectivity unless a record’s share flag is set. Topology, sizing, and the air-gapped install are on the Deployment page.
3. Data classification and lifecycle
| Category | Storage | Sensitivity |
|---|---|---|
| Accountability metadata | PostgreSQL (your DB) | Business-sensitive |
| Audit vault | PostgreSQL (your DB) | Integrity-critical |
| API credentials | PostgreSQL (your DB) | Secret |
| Webhook secrets | PostgreSQL (your DB) | Secret |
Not stored, not inspected
Model prompts, completions, or training data
Business document content - AGLedger validates structure, never value
PII beyond what customers include in record metadata (customer-controlled)
Payment card data or banking credentials
All data resides in the PostgreSQL instance you provision. No external data stores, no phone-home: AGLedger collects no usage data and operates no service that receives data from your deployment.
Retention and deletion. The customer controls retention as the database operator. The audit vault is append-only by design, which is in deliberate tension with deletion regulations (GDPR Article 17, CCPA): Signed Statements hold accountability metadata, while record criteria and completion evidence live in separate tables that can be archived or purged. In encrypted mode (§4) the server stores only the encrypted evidence envelope and an evidence hash, so destroying the encryption key renders the content irrecoverable while chain integrity is preserved - cryptographic erasure.
4. Cryptographic architecture
| Layer | Standard | Purpose |
|---|---|---|
| Credential storage | HMAC-SHA256 | API keys stored as hashes, never plaintext |
| Webhook signing | HMAC-SHA256 · Ed25519 (RFC 9421) | Delivery integrity by default; RFC 9421 signatures for non-repudiable Settlement Signals, verifiable against the published Server keys |
| Federation transport | Ed25519 per-request signing; RFC 8785 (JCS) | Peer authentication with per-instance keys over a domain-separated sign input; canonical JSON for body hashes and schema digests |
| Audit envelope | COSE_Sign1 (RFC 9052, tag 18) + Ed25519 | Signed Statement envelope; the COSE_Sign1 bytes feed the SHA-256 hash chain |
| Payload format | in-toto v1 Statement, CBOR per RFC 8949 §4.2.1 | Deterministic encoding of the audit payload |
| Identity in header | CWT Claims, RFC 8392 (label 15) / RFC 9597 | Issuer, subject, and actor named in the signed protected header |
| Data at rest | SHA-256 hash chain / AES-256-GCM | Vault tamper evidence; secret storage |
| Client-side encryption | AES-256-GCM / AES-256-GCM-SIV | Server-blind completion evidence: the server stores the encrypted envelope and an evidence hash; criteria stays server-readable |
Independent keys. The vault signing key and the federation keys are separate per-instance keys, generated independently and never derived from each other.
Algorithm identifiers everywhere. Every artifact carries its alg, so verification dispatches on the recorded algorithm instead of assuming one (§14).
Domain-separated derivation. Where keys are derived, HKDF-SHA256 with purpose-specific labels keeps them cryptographically independent.
Federation payload encryption is not yet on. Each Server exchanges an X25519 public key at handshake for a future encrypted-payload channel; v1 signs federation messages but does not encrypt them at the application layer - transport privacy is TLS. What crosses the boundary is limited by schema (§8).
5. Audit vault integrity and offline verification
The audit vault is the core primitive: an append-only ledger of every accountability event. Each entry surfaces to customers as a Signed Statement:
| Tampering | Mechanism | Detection |
|---|---|---|
| Insertion | Hash chain breaks previous_hash link | LINK_BROKEN |
| Deletion | Sequential chain_position gap | POSITION_GAP |
| Modification | Recomputed hash mismatch | HASH_MISMATCH |
| Payload edit | Visible payload jsonb diverges from signed bytes | payload_drift |
| Forgery | Ed25519 signature fails against registered key | signature_invalid |
Enforcement layers
Database: UPDATE and DELETE are revoked on the vault tables; partition-level TRUNCATE is blocked by trigger. A privileged operator who edits the human-readable payload jsonb is caught at verification as chainIntegrityReason: 'payload_drift' - the signed envelope, not the visible copy, is the source of truth.
Application: vault writes occur inside the same transaction as the state change - the entry exists if and only if the state change committed.
Cryptographic: the hash chain and signatures provide tamper evidence independent of database access controls.
Operational: signed checkpoints on a configurable cadence (6 hours by default). Optional external anchoring to S3-compatible storage with COMPLIANCE-mode object lock.
Offline verification
Verification means one thing in this document: checking the cryptography. Three properties are independently checkable: the signatures are genuine against the instance’s published keys, the hash chain recomputes end to end (a break is located at the exact position it occurs), and the visible payload has not drifted from the signed bytes. A pass does not prove the claim inside a record was true or the work behind it good - the principal renders that verdict at the Gate, and verification confirms the verdict is authentic and untampered like every other entry.
GET /v1/records/{id}/audit-export exports a record’s chain as a self-contained signed bundle for verification on a machine that never talks to AGLedger. The published keys are the only external input, served unauthenticated at GET /v1/verification-keys and GET /.well-known/agledger-vault-keys.json, with active and retired keys both returned so historical chains verify across rotations. The standalone verifier, the CLI, the SDKs, and the MCP server all check the same exported bytes; step-by-step commands are in the offline verification guide.
No AGLedger code is required on the verification path. Every entry is a standard COSE_Sign1 envelope, so a stock COSE library can confirm a chain on its own; our verifier is a convenience, not a dependency. The chain also exports as DSSE envelopes wrapped in Sigstore Bundle format (v0.3, BYO-key), verifiable with cosign in private-infrastructure mode. Where the Transparency Service is enabled, an export can include SCITT Receipts - RFC 9162 Merkle inclusion proofs in COSE, opt-in via ?receipts=true - proving an entry was admitted to the transparency log at a known position, independent of the chain itself.
Because verification needs nothing but the bytes and the published keys, an auditor, a counterparty, a regulator, or a court can confirm a chain years later - with the Server shut down, the license lapsed, or the vendor gone. The proof outlives the vendor.
6. Key management and rotation
The vault signing key is the trust root of the chain. It is supplied as VAULT_SIGNING_KEY - required in production and customer-held: AGLedger LLC never possesses it. The customer protects the private key with their own secrets manager (§12).
Zero-downtime rotation
The current key moves to VAULT_SIGNING_KEY_PREVIOUS and the new key becomes VAULT_SIGNING_KEY, keeping prior entries verifiable through the transition.
A rolling restart picks up the change; the rotation is then activated in the key registry (POST /v1/admin/vault/signing-keys/rotate), retiring the old key and activating the new one.
New entries sign with the new key; historical entries remain valid because verification resolves retired keys from the registry. The chain stays continuous - no re-signing.
Key loss does not invalidate history. Verification uses the public key recorded in the database, not the private key in the environment. Losing the private key stops new signing; it does not retroactively break the existing chain. The registry supports unlimited rotations and records an algorithm per key, so a chain spanning two algorithms verifies entry by entry against the key that signed it (§14).
7. Authentication and access control
Two authentication paths, same protocol on the wire. Enterprise installs lead with OIDC-bound ephemeral signing certificates: agents exchange a JWT from the customer’s own identity provider (Auth0, Okta, Azure AD, Keycloak, GCP WIF, K8s service-account tokens) for a short-lived AGLedger cert via POST /v1/auth/oidc/cert - 10 minutes by default, configurable per issuer up to one hour - and present it as the Bearer credential. No agent holds a long-lived key; blast radius on credential compromise is minutes.
Long-lived API keys remain fully supported for development, the quickstart, and single-operator installs. Keys are never stored in plaintext - the server computes HMAC-SHA256 and looks up the hash. Both credential types produce the same chain envelope, and the actor identity each carries is named inside the signed payload (§1). Trust anchors are configured per-org via POST /v1/admin/trusted-issuers - one row per IdP per purpose with an applies_to discriminator (agent / principal / admin / any); JWKS endpoints are auto-discovered via OIDC well-known. See the Authentication guide.
| Role | Capabilities | Typical user |
|---|---|---|
| Platform | System administration, enterprise provisioning, vault management (cross-org by design) | AGLedger operator |
| Admin | Configuration, oversight, compliance exports, key management | Org administrator |
| Agent | Record lifecycle operations scoped to authorized actions | AI agent, RPA bot, service |
Each API key carries a scope list, and anti-escalation prevents creating keys with broader scopes than the creating key. Agent and admin access is org-scoped - the platform role is the one deliberate cross-org identity, held by the operator. Additional controls: per-key IP allowlisting, key expiration, and the optional per-request agent signature (§1).
8. Federation and privacy boundary
Across organizations, federation is peer-to-peer signed-message transport over TLS. Each Server signs every request with its own per-instance Ed25519 key over a domain-separated sign input (method, path, RFC 8785-canonical body hash, timestamp, nonce); there is no shared key and no central coordinator.
Crosses the boundary
Server identity + public keys
Agent IDs
Record ID, contract type
State transitions (state, timestamp, signature)
Gate verdict (accept/reject)
Settlement Signal (SETTLE/HOLD/RELEASE)
Never crosses
Record criteria (actual acceptance terms)
Completion evidence (work product)
Audit vault entries
Prompts, context, or business logic
API keys or auth credentials
Webhook URLs or delivery payloads
Each Server remains sovereign: it records the signed bytes a peer sent, verifies them against the peer’s published key, and never holds the peer’s underlying business data. Transport mechanics live on the Federation page.
9. Application security
Schema-first validation. Every endpoint declares request and response JSON Schemas enforced by the framework. Unknown fields rejected, no implicit type coercion. 1 MiB global request limit, 65 KiB record limit, 20-level JSON depth cap.
SQL injection prevention. All queries use parameterized SQL. Sort and filter columns are validated against explicit whitelists.
Webhook SSRF protection. Layered validation: private IP ranges, loopback, cloud metadata endpoints, alternative IP encodings, DNS re-resolution at connect time (TOCTOU), internal hostname suffixes, embedded credentials, HTTPS-only.
Expression engine sandboxing. jsep AST parser (not eval). 50 AST nodes, depth 10, 1,000 operations max. No access to global scope, prototype chain, or Node.js APIs.
Rate limiting. Every authenticated key shares one per-key budget of 1,000 requests/min by default; platform keys, as root credentials, are effectively exempt (a 100,000/min ceiling applies). Unauthenticated traffic is IP-keyed with its own budget, and hot write routes carry tighter caps beneath the per-key budget (POST /v1/records is 200/min). State is in-memory per instance by default, with a PostgreSQL store option for multi-replica consistency. Errors return as RFC 9457 problem details.
10. Infrastructure hardening
Container
Red Hat UBI 10 minimal base (RPM-managed Node and OpenSSL, updated every build)
Node permission model denies child_process
Non-root user (UID 65532)
Read-only filesystem + tmpfs for /tmp
512 MiB memory, 1.0 CPU limits
Liveness + readiness health probes
File-based secrets injection
Database
Separated identities: a least-privilege runtime role, a read-only monitor role, and a distinct owner connection used only for migrations
TLS required in production (sslmode=verify-full recommended)
Advisory-locked, checksummed migrations
Node.js 24 LTS, pinned dependencies
11. Threat model
| Threat | Controls |
|---|---|
| Audit trail tampering | Hash chain + signatures + DB enforcement (UPDATE/DELETE revoked, TRUNCATE blocked) + external checkpoints; payload edits surface as payload_drift |
| Attribution forgery | Principal and acting credential are inside the signed payload; re-pointing an entry invalidates the signature |
| Cross-tenant access | Org-scoped agent and admin access; scoped API keys; principal enforcement |
| API key compromise | HMAC-hashed storage; IP allowlisting; expiration; scopes limit blast radius; ephemeral certs cap exposure at minutes |
| Webhook SSRF | Layered validation including DNS re-resolution; HTTPS-only |
| Federation MITM | TLS + per-request Ed25519 signing with per-instance keys |
| Signing key compromise | Key registry supports immediate rotation; external anchors verify pre-compromise entries |
| Denial of service | Tiered rate limiting; size caps; depth limits; handler timeouts |
Explicitly out of scope
Compromised principals. If the entity creating records is malicious, AGLedger faithfully records what they reported. We attest accountability, not truthfulness - the chain proves what was said and signed, not that it was correct.
Content-level threats. AGLedger validates structure, not business content; zero content inspection is the boundary the product is designed around.
Infrastructure compromise. OS, network, and physical security are the customer’s responsibility.
12. Privacy, data protection, and shared responsibility
AGLedger is self-hosted software: in the typical deployment, AGLedger LLC is neither a data processor nor a data controller. Residency follows the customer’s database placement, license validation is an offline Ed25519 check, and no AGLedger LLC system sits in the data path. Zero sub-processors for customer data in the standard deployment; no international transfers when sharing is off; encrypted mode enables cryptographic erasure (§3).
AGLedger provides
Application security (validation, SSRF, SQLi prevention)
Cryptographic integrity (hash chain, signatures, agility)
Access control (RBAC, scoping, rate limiting)
Secret handling (HMAC, AES-256-GCM, log redaction)
Container hardening (non-root, read-only filesystem)
Database role separation
Customer provides
Infrastructure security (network, OS, physical)
Database encryption at rest
TLS certificate management
Vault signing key protection (secrets manager)
Backup and disaster recovery
Monitoring, alerting, and SIEM integration
13. Compliance mapping
AGLedger captures signed records, delegation chains, and cross-org evidence transport regardless of regulation; downstream, these map to the obligations below. Detailed crosswalks live on the dedicated pages.
EU AI Act: Articles 12 and 14 - event logging and human oversight
NIST AI RMF: GOVERN, MAP, MEASURE, MANAGE
ISO 42001: Capability crosswalk
ISO 27001: Annex A controls A.8, A.9, A.10, A.12
NIST 800-53: AC, AU, IA, SC, SI families
SOC 2: not a certification - AGLedger is self-hosted software, not a service organization, so your deployment runs under your existing certifications. Enterprise customers can review the source code and request a SOC 2 alignment report mapping AGLedger’s controls to the Trust Services Criteria (internal readiness assessment completed March 2026).
14. Algorithm agility and post-quantum readiness
All algorithms are current NIST-approved. NIST finalized post-quantum standards in August 2024 (ML-KEM / FIPS 203, ML-DSA / FIPS 204, SLH-DSA / FIPS 205).
Per-key algorithm registry. The signing-key registry derives the algorithm from the key material at registration, and verification dispatches on it rather than assuming one. Ed25519 is the default; ECDSA P-256 (ES256) is the second shipped algorithm, enabled by explicit opt-in for hosts whose crypto provider excludes EdDSA (see FIPS 140 hosts). Adding a third is a registry entry and a verifier release, not a format change.
No re-signing required. New entries use the new algorithm; old entries remain valid against the retired key that signed them. A chain spanning two algorithms is continuous.
Hybrid (classical + PQC) signatures are expected industry-wide in 2027–2028; the registry design means adopting them requires no customer action today.
15. Continuity and releases
As self-hosted software, RPO and RTO depend on the customer’s infrastructure and backup strategy. AGLedger provides the tooling: backup.sh, restore.sh, support-bundle.sh, and health probes for orchestrator-level recovery. The chain is self-verifying: after restoring from any backup, run the vault integrity check to confirm continuity.
Releases use semantic versioning with checksummed, transactional database migrations. Release artifacts are keyless-signed (OIDC → Sigstore → Rekor) with a signed SBOM, verifiable with stock tooling against the public transparency log.
Security fixes are always free - regardless of support contract status, distributed as new versions with CVE-referenced advisories.
16. Incident response
Report vulnerabilities to security@agledger.ai. Critical reports are acknowledged within 24 hours with a 72-hour patch target; high severity within 48 hours with a one-week patch target.
If vault integrity verification detects tampering, the failure is logged with full context (chain position, expected vs. actual hash, signing key ID). Failed entries are flagged but never modified - the evidence of tampering is itself part of the audit record.
Related
AGLedger is a product of AGLedger LLC. This document describes the security architecture of AGLedger software. It is not a guarantee of security and should be evaluated alongside your organization’s specific risk assessment. Contact: security@agledger.ai