Skip to content

Security

Sill’s security posture rests on a small number of load-bearing primitives: every governed surface is signed with ed25519 and verifiable against a public JWKS; every governed decision is written into an append-only, Merkle-chained audit envelope; the architecture handles only opaque processor tokens so raw cardholder data never enters any Sill system; tenants are isolated by account_id / site_id at every boundary; and the only credential a human ever presents to Sill is a magic-link sign-in token. The full marketing overview lives at sill.so/security; this page is the technical reference.

Signing — ed25519, JWS-detached, public JWKS

Section titled “Signing — ed25519, JWS-detached, public JWKS”

Every governed surface Sill publishes — the per-site agent card, the ARD ai-catalog.json trust manifest, every audit record, every exported audit bundle — is signed with an ed25519 key per RFC 8032. The signed payload is a JWS in compact, detached serialization with alg: EdDSA per RFC 7515 and RFC 8037. Canonicalization is RFC 8785 (JCS) — without a deterministic canonicalizer two semantically equal JSON objects could produce different signed bytes, and verification would not survive round-trips across implementations.

The public half of each signing key is published at a standard JWKS endpoint:

GET https://edge.sill.so/.well-known/jwks.json

A third party can verify any Sill signature end-to-end using only:

  1. The JWKS above.
  2. An RFC 8785 JCS canonicalizer.
  3. An off-the-shelf ed25519 library (@noble/ed25519, pynacl, tweetnacl, OpenSSL).

No Sill SDK, no Sill code, no Sill account is in the verifier path. The full recipe — including a minimal JavaScript sketch and a tampering smoke test — is at Verify a signature. The endpoint, headers, and key shape are documented at Public JWKS.

SurfaceSigned scopeWhat the signature does NOT cover
Agent cardThe canonical card payload — protocol_version, skills[], capabilities.Skill availability at the wire — the card is a discovery surface.
ARD ai-catalog.jsonThe trust manifest (host identity + provenance).Per-entry url / capabilities / description — those rest on did:web + TLS per the ARD spec.
Audit recordThe record with envelope_signature and merkle_root stripped, JCS-canonicalized.The merkle_root written back at end-of-day batch close (excluded from the signing input by construction).
Audit bundle exportA SHA-256 over a domain-separated prefix concatenated with the JCS-canonical body.The chain and Merkle structure of the contained records — a complete verifier rechecks per-record signatures + recomputes batch roots.

Every governed interaction Sill observes is written into the audit envelope: append-only, signed per record, chain-linked to its predecessor, and folded into a per-(site, decision-class, UTC-day) Merkle batch.

flowchart LR
  WRITE[Edge / origin writer] --> SIGN[Sign + chain-link<br/>ed25519 over JCS]
  SIGN --> ROW[(Immutable audit_record row)]
  ROW --> BATCH[End-of-UTC-day batch closer]
  BATCH --> ROOT[Merkle root written back<br/>per site, decision-class, day]
  ROOT --> EXPORT[Signed bundle export]

The append-only property is structural, not a permission setting: any byte-level change to a stored record breaks the per-record envelope signature, breaks the prev_record_hash of the next record, and breaks the Merkle root that contains it. Each chain is domain-separated at genesis by site_id and decision class, so a discovery record can never be substituted for a transactional record on the same site, and two sites’ chains cannot collide. The full record shape, chain construction, batch math, and end-to-end verifier walkthrough are at Audit envelope.

No fund custody — Sill never holds money

Section titled “No fund custody — Sill never holds money”

Sill issues signed authorizations and signed audit records. The merchant’s existing payments processor (Stripe today) holds the card, authorizes the charge, settles, and pays out. No funds enter a Sill-controlled account at any step of the flow.

sequenceDiagram
  autonumber
  participant A as Agent
  participant E as Sill edge<br/>(mandate + policy)
  participant O as Sill origin<br/>(audit + connectors)
  participant S as Stripe
  participant M as Merchant payout

  A->>E: Signed mandate
  E->>E: Policy evaluation
  E->>O: authorize(mandate, opaque token)
  O->>S: Charge against merchant-saved pm_*
  S-->>O: Charge id + status
  O->>O: Append signed, chain-linked audit record
  S->>M: Settlement + payout (no Sill leg)

The architecture is intentional: Sill is the identity / intent / proof + payment-authorization layer in front of the merchant’s processor, not a replacement for it. See Payments for the Stripe rail.

PCI-minimal architecture — opaque tokens only

Section titled “PCI-minimal architecture — opaque tokens only”

Sill handles only opaque processor tokens — Stripe pm_* / tok_* / Shared Payment Token references. Raw Primary Account Numbers (PANs), expiry dates, CVCs, and full track data never enter any Sill system. The card data and the funds flow remain inside Stripe, whose PCI scope already covers them.

This architectural minimization is enforced at two levels:

  1. Architecture. The mandate engine takes an opaque token reference as input, never raw card material. The Stripe connector calls Stripe with that reference; Stripe charges and returns a charge id.
  2. CI grep gate. A repository-level CI check fails any commit whose source or test payloads match PAN-shaped digit patterns or the field names card_number, cvc, cvv, pan, card_expiry, so the “opaque tokens only” property cannot regress silently.

Sill is multi-tenant. Every tenant boundary in the data model and the request path is scoped by account_id (the merchant org) and site_id (the registered domain). Both are ULIDs; domain objects carry prefixed string IDs (mnd_…, agent_…, rec_…).

Isolation enforcement points:

  • Routes. Per-site endpoints (/v1/agent-card/{site_key}.json, /v1/catalog/{site_key}.json, /v1/mcp/{site_key}) include the site key in the URL; the edge resolves it to a site_id before any data access.
  • Session. Magic-link sessions carry the account_id. Every API route asserts the session’s account against the row’s account_id before returning data.
  • Audit chains. Each site keeps two independent audit chains, domain-separated at genesis by site_id and decision class. A record from one site cannot be substituted into another site’s chain — the chain link or the genesis hash will fail.
  • Connector credentials. Stripe Connect account ids and Shopify OAuth tokens are stored per account_id; the connector resolves credentials by the request’s account, never by client-supplied input.

The only credential a human ever presents to Sill is a magic-link sign-in token, mailed to a verified email address. There are no passwords to phish, no password databases to leak, and no password reset flow to social-engineer. Sessions are scoped to *.sill.so so the dashboard at app.sill.so and the marketing surfaces at sill.so share a single login.

  • Auth path: magic link only in production today.
  • Session cookie: .sill.so cross-subdomain, with Secure + HttpOnly + SameSite=Lax.
  • SSO: on the roadmap. Not available today.

A small set of operational properties round out the posture:

  • Region. US-East only today. Merchant-controlled data residency is not a current capability.
  • Edge vs origin separation. Mandate engine + signing surfaces at the edge. Audit storage, registry, connectors, billing webhooks at the origin. The split bounds blast radius — an edge issue cannot mutate audit history; an origin issue cannot forge an edge-signed surface (the signing key lives at the edge).
  • Key management. Signing keys live in a managed key store: a public-verifiable edge key for the agent card and ARD catalog, and separate origin keys for the audit envelope and bundle exports. The JWKS lets verifiers pick a key by kid.
  • Backups. The database is backed up two ways: point-in-time recovery with a 7-day window, and a nightly logical backup encrypted before it leaves the backup runner — the decryption key is held offline and exists on no cloud provider — then stored off-platform on a 35-day rotation. Backups are restore-tested on a quarterly drill, not just taken; the first drill passed with a zero-error restore.
  • Access control. Production access is restricted to authorized operators. Every infrastructure provider account in the stack requires multi-factor authentication.
  • Deploys. Origin API deploys are blue/green: the new instance must pass health checks before it receives any traffic, so a failed deploy never serves requests. (A deploy-safety property, not an uptime or SLA claim — Sill publishes neither today.)
  • Incident notification. Merchants affected by a confirmed security incident are notified without undue delay, and within 72 hours of confirmation.

The signed audit chain is retained for the life of the account — it is the product’s evidentiary core, append-only and tamper-evident, and it is designed to hold no personal data (principals are referenced pseudonymously). Operational logs (escalation-notification, catalog-sync and invite telemetry, smoke-test history) are retained on bounded windows — roughly 90 days, and 365 days for red-team results — and then removed.

Account deletion. An account owner can request deletion from the dashboard. To confirm, they enter a single-use code emailed to the owner’s verified address — so a stolen dashboard session alone cannot trigger it. On request the account’s sites are taken offline immediately and every session is signed out, and a 30-day grace window opens during which the owner can cancel and fully restore access simply by signing back in (a banner offers a one-click restore). After the grace window, the account is permanently deleted: all personal data — owner and team identities, connector credentials, buyer details, contact information — is erased, and the signed audit records are retained in anonymized form so the tamper-evident chain stays intact without holding personal data. The full step-by-step is in Deleting your account.

Backups follow deletion. Because encrypted backups rotate on a 35-day window (see Backups above), a record erased from production is also purged from the most recent backup within 35 days of that erasure — deletion is not left behind in an old backup.

Compliance posture (mappings, not certifications)

Section titled “Compliance posture (mappings, not certifications)”

Sill publishes framework mappings, not certifications. The control-by-control mappings — OWASP Top 10 for Agentic Applications (2026, v1.0; Sill’s primary OWASP reference), OWASP LLM Top 10 (2026), MITRE ATLAS (2026.07), NIST AI RMF 1.0 — describe where named Sill controls address the named framework risks. They are not third-party attestations.

For the canonical control-by-control mapping table, see Compliance and the marketing-site standards page at sill.so/standards.

External frameworks Sill’s controls are designed against:

  • OWASP Top 10 for Agentic Applications (2026, v1.0) — covered for ASI03 + ASI10; partial for ASI01, ASI02, ASI04, ASI06, ASI08, ASI09; ASI07 covered for registered-agent delegation; ASI05 out of scope.
  • OWASP LLM Top 10 (2026) — LLM01 Prompt Injection, LLM06 Excessive Agency, LLM10 Unbounded Consumption, LLM02 Sensitive Information Disclosure (partial).
  • MITRE ATLAS — tactic-level evasion / exfiltration / impact / credential access; AML.T0096 covered; AML.T0011.002 + AML.T0098 + AML.T0113 / AML.T0091.001 (web session cookies) + AML.T0051 / AML.T0054 partial; AML.T0100 + AML.T0114 not covered.
  • NIST AI RMF 1.0 — audit envelope + bundle export support the Measure and Manage functions.

These mappings are the work product, not certifications. See Compliance.

Report security issues to [email protected]. Please include reproduction steps and the affected surface (edge endpoint, dashboard route, audit format, etc.). Sill is a trust product; security reports are taken seriously and acknowledged.

Machine-readable contact details are published at sill.so/.well-known/security.txt per RFC 9116.

How do I verify a Sill signature without trusting Sill? Fetch the JWKS at https://edge.sill.so/.well-known/jwks.json, canonicalize the payload with RFC 8785 (JCS), and verify the detached JWS with an off-the-shelf ed25519 library. The step-by-step recipe + a minimal JavaScript sketch + a tampering smoke test are at Verify a signature.

Can a Sill audit record be edited or deleted? No. The record is signed with ed25519 over the JCS-canonical form, chain-linked to the previous record by prev_record_hash, and folded into a per-day Merkle batch. Any byte-level change breaks all three. The only post-write change is the end-of-day write-back of merkle_root, which is excluded from both the signing input and the chain-hash input by construction.

Does Sill ever see raw card numbers? No. The mandate engine and the connector layer accept only opaque processor tokens (Stripe pm_* / tok_* / SPT references). Raw PANs never enter any Sill system. The “opaque tokens only” property is enforced by both architecture and a CI grep gate.

Is Sill PCI-certified? No. Sill holds no PCI attestation, ROC, or SAQ. The architectural minimization above keeps cardholder data and the funds flow inside the merchant’s processor (Stripe). PCI certification is future work and is not claimed today.

Is Sill SOC 2 / ISO 27001 certified? No. Sill publishes framework mappings and will not claim any third-party certification until accredited audits complete. See Compliance.

What stops one tenant from reading another tenant’s data? Every tenant boundary is scoped by account_id + site_id. Per-site routes carry the site key in the URL and resolve it before data access. Dashboard sessions assert the account on every row. Audit chains are domain-separated at genesis — a record from one site cannot be inserted into another site’s chain because the chain link or the genesis hash will fail.

What auth does Sill support? Magic link only today, scoped to *.sill.so. SSO is on the roadmap.

What region does Sill run in? US-East only today. Merchant-controlled data residency is not a current capability.

External references: