Service Spec v1
A small, closed contract for discovering a Service and proving that its control plane preserves the Space and Capsule boundaries.
Declare only what the platform enforces
Every conforming source tree contains shimpz.driver.toml. Unknown fields, missing fields,
malformed TOML, unsupported values, and repeated operations must stop the Service before it listens.
schema_version = 1
id = "postgresql"
title = "PostgreSQL"
version = "3.0.0"
summary = "Managed PostgreSQL databases isolated per Capsule and App."
interface = "shimpz.postgresql/v1"
scope = "space"
credential_policy = "managed"
data_plane = "direct"
port = 7072
health_path = "/healthz"
metadata_path = "/v1/driver"
[capabilities]
operations = [
"capsule.provision",
"capsule.finalize",
"capsule.drop",
"capsule.app.create",
"capsule.app.drop",
]This example is byte-compatible with the current PostgreSQL manifest. App and capsule.app.* inside the block are legacy wire identifiers; the public workload name is
Assistant, and renaming those operation IDs requires a versioned interface migration.
The machine-readable shape contract is the Service Manifest v1 JSON Schema.
Separate artifact, interface, and topology
schema_versionselects this manifest schema. v1 accepts only integer1.id,title,summary, andversionidentify the Service artifact.interfaceversions the capability API independently from the artifact.scopeisspace. Tenant isolation belongs to resources and authorization, not to duplicate Service processes.credential_policyisnone,managed, ormanaged-or-byok. There is deliberately no required-BYOK mode.credential_schema_pathis an absolute internal HTTP path required only formanaged-or-byok. Services usingnoneormanagedmust omit it.data_planeisdirectwhen the runtime issues a scoped connection, orbrokeredwhen bytes and operations continue through the Service. This field does not claim that the Assistant capability-binding runtime is released.portis the Service's fixed internal container port.health_pathandmetadata_pathidentify distinct, unauthenticated discovery endpoints on the private Space network.capabilities.operationsis the exact allowlist implemented by its control API.
An operation name is not a payload schema
Every interface identifier must resolve to versioned Service documentation that defines its
transport, routes, authentication authorities, request fields, response fields, status semantics,
and retry behavior. capabilities.operations is a discovery allowlist; it does not replace
that interface contract. The PostgreSQL reference documents shimpz.postgresql/v1 with its
implementation.
Conformance is behavior, not a manifest badge
- The health endpoint returns only a generic liveness verdict.
- The metadata endpoint returns the validated manifest and no secret or tenant inventory.
- Discovery endpoints are not Internet routes; they remain reachable only on private Space networks.
- Every state-changing operation is authenticated, allowlisted, input-validated, and audited.
- Tenant and provider resource identifiers are derived and validated by the Service, not trusted from an Assistant request.
- Lifecycle retries cannot widen access, duplicate authority, or report success over known residue.
- One Capsule cannot enumerate, read, mutate, or delete another Capsule's resources.
- The Service's control credential never enters an Assistant or its Capsule data plane.
BYOK is an optional Capsule override
none means the capability has no provider credential. managed means only the
Space operator configures it. managed-or-byok uses the Space-managed credential by
default and permits an authenticated Captain to set or rotate an override for one Capsule; clearing
it returns that Capsule to the managed credential. A missing or invalid update fails closed without
replacing the last valid configuration.
A BYOK value is Capsule-scoped secret configuration: it cannot appear in the manifest, discovery metadata, logs, error bodies, or another Capsule, and it must pass through the platform's secret boundary rather than an Assistant-owned environment file.
The Admin renders data; it never executes Service JavaScript
A managed-or-byok Service serves a credential-form document from its declared internal
path. The platform fetches that path through the authenticated control plane, validates the complete
document, and renders it with a platform-owned component. It never evaluates a script, imports a
Service component, opens an iframe, or follows a provider URL supplied by the document.
{
"schema_version": 1,
"owner_scope": "capsule",
"cardinality": "many",
"profiles": [
{
"id": "access-key",
"kind": "secret-fields",
"title": "Access key",
"fields": [
{
"id": "account_id",
"type": "text",
"label": "Account ID",
"required": true,
"format": "account-id",
"min_length": 1,
"max_length": 128
},
{
"id": "api_key",
"type": "secret",
"label": "API key",
"required": true,
"format": "api-key",
"min_length": 16,
"max_length": 4096,
"write_only": true
}
]
}
]
}The canonical shape is the Service Credential Form v1 JSON Schema. It is closed: unknown profile kinds, fields, formats, and options fail before the Admin displays or submits anything. Profile and field identifiers must also be unique within their arrays.
owner_scopeis alwayscapsule.cardinalityisoneormanycredential sets per Capsule.secret-fieldsaccepts onlytext,secret, andselectfields. It has no executable validator, regular-expression field, or endpoint URL.- Every text or secret field selects a named v1 format and declares tighter minimum and maximum lengths. The Admin and Service both validate the same constraints; client validation is never authority.
- Secret fields require
write_only: true. They are accepted only during create or rotate and are never returned by list, discovery, verification, or error responses.
Named validation replaces arbitrary regex
v1 text formats are plain-text (256), account-id (128), bucket-name (63), hostname (253), region (64), tenant-id (128), and username (128). Secret formats are access-key-id (256), api-key (4096), password (1024), private-key (16384), secret-access-key (4096), and secret-token (4096). Numbers are maximum characters; the declared max_length may only narrow them, and min_length cannot exceed it.
A select contains at most 64 closed, unique options. Provider endpoints, redirects, and
network destinations come from audited platform adapters, never from a form value or form metadata.
Create, list, verify, rotate, and remove share one contract
credential.createvalidates ownership, the selected profile, every field, and a non-destructive provider check before atomically storing a server-generated opaque credential ID at generation1. An idempotency key prevents a lost response from creating a duplicate.credential.listreturns only the credential ID, profile ID, label, status, generation, and timestamps. It never returns a submitted value, encryption envelope, or provider token.credential.verifyexercises the stored set through its Service and returns only a typed verdict and trace ID; verification neither reveals values nor advances the generation.credential.rotaterequires the complete replacement plusexpected_generation. The Service verifies first, commits with compare-and-swap, then increments the generation. A failure or stale generation preserves the previous set unchanged.credential.removealso requiresexpected_generation, revokes use before reporting success, and is idempotent for an already removed exact ID. Foreign IDs remain invisible.
Encryption at rest uses authenticated encryption. Its additional authenticated data binds at least the Service ID, schema version, Capsule ID, credential ID, profile ID, and generation. Moving ciphertext between any of those identities must fail authentication. Keys, ciphertext, nonces, Bearers, and OAuth material never enter logs or public audit fields.
No active Capsule override means the Service uses the Space-managed credential. Explicit removal returns to that managed fallback. A rejected update leaves the last valid override active, while an expired or failing configured override fails closed instead of silently widening authority through the managed key.
Service Spec v1 defines credential custody and lifecycle, but the Assistant capability-binding runtime has not been released. Assistants cannot consume these credential sets today. A future binding must carry only an opaque reference and an exact operation grant; secret values remain inside the Service boundary.
Adapters own OAuth; passkeys authenticate the Admin
An oauth2-authorization-code profile declares only an Admin-allowlisted adapter_id, bounded scopes, and mandatory PKCE S256. Unknown adapters or scopes
fail closed. The document cannot carry authorization URLs, token URLs, redirect URLs, client secrets,
or executable callback code.
The central OAuth broker owns provider endpoints and client registration, generates one-use state and the PKCE verifier, checks the exact callback, exchanges the authorization code server-side, and stores access and refresh tokens through the same Capsule-scoped secret boundary. OAuth codes and tokens never pass through browser storage, URL logs, a Service manifest, or an Assistant environment.
A passkey is a WebAuthn credential for signing in to the Shimpz Admin. It authorizes the Captain's intent but is never a Service profile, provider credential, or value forwarded to a Service.
Redpanda may receive post-commit events containing opaque credential references, generation, operation, status, and trace identifiers. Form values, authorization codes, access or refresh tokens, ciphertext, nonces, and encryption keys never enter an event or topic.
The target Redpanda topology is one Service instance per Space. Each Capsule receives its own authenticated principal, bounded topic and group prefixes, ACLs, and quotas; sharing between Assistants or Capsules requires literal, reviewed grants. It carries only post-commit events and never secrets.
The OAuth broker, Cloudflare adapter, passkey sign-in, and Redpanda event integration described here are
architecture/spec only. The current Service credential runtime executes the R2 secret-fields lifecycle; it does not implement those identity and event components.
No required language or framework
Python, Rust, or another runtime may implement the contract. Conformance depends on the manifest, external interface, isolation proofs, and failure behavior. Repository location and source language are intentionally absent from the runtime schema.