Guide · Packs
Write an integration without our code.
A declarative Pack binds operations of an existing HTTP API to Ardyn’s generic executor, with a manifest, declared permissions and your signature. Nothing runs when it’s installed. You, a vendor or a partner follow the same contract as Ardyn’s own packs.
How this format was tested
A separate author was given only this specification — no Ardyn source and no help. They wrote a service Ardyn had never seen and a Pack for it, and signed it. It installed into a fresh workspace and ran an operation that produced a verifiable receipt. Invalid, path-traversal, incompatible and tampered packs were refused, as was a permission expansion without approval. Upgrade, rollback and removal all kept old receipts verifiable: 17 of 17 cases. The author was an automated agent working in an isolated directory on the same machine. That is a test of the documentation, not an independent security review. Their 18 questions are answered in the clarifications below.
Document shape
{
"format": "ardyn-pack/2",
"manifest": { … ArdynIntegrationPackV1 … },
"bindings": {
"openapi": {
"base_url": "https://api.example.com",
"spec": { … an OpenAPI 3.0.x / 3.1.x document … },
"operations": ["getFiring"]
}
},
"permissions": { "hosts": ["api.example.com:443"], "effects": ["read"] },
"runtime_compat": ">=1.0.0, <2.0.0",
"files": [ { "path": "README.md", "content": "…" } ],
"signature": { "public_key": "<64 hex>", "signature": "<128 hex>" }
}
pack_id (unique, non-empty), display_name, version (semver string), schema_version (integer 1), auth_methods (non-empty array of strings, e.g. ["api_credential"]), capabilities (array from: connect, authenticate, discover, health, capabilities, subscribe, poll, normalize, verify_native, execute, correlate, limitations, disconnect), passive (boolean), evidence_ceiling (one of SELF_ASSERTED, SOFTWARE_OBSERVED, PROVIDER_REPORTED, TELEMETRY_BACKED, SERVICE_RECEIPT), mappings, limitations, fixtures (arrays of strings), conformance (string).base_url host:port must appear in permissions.hosts. Implicit ports apply (https → 443, http → 80). A path prefix in base_url is kept. Each listed operation id must exist in spec, and its effect (GET/HEAD/OPTIONS = read, others = write) must be in permissions.effects. The spec may contain other operations; only listed ones become capabilities.[] when there are none. Safe relative paths only (no leading /, no .., \, : or empty segments). At most 64 files; the whole request at most 2 MiB.Signing
Take X = {"format", "manifest", "bindings", "permissions", "runtime_compat", "files"}. Serialize it as canonical JSON: compact, no whitespace, object keys sorted recursively in byte order, strings escaped as standard JSON with non-ASCII left as UTF-8, numbers as written (prefer integers). Compute the lowercase hex BLAKE3-256 of those bytes, and form the string "blake3:" + hex. Sign the UTF-8 bytes of that string with Ed25519. Put the raw 32-byte public key and 64-byte signature, both lowercase hex, in signature.
A valid signature shows the pack wasn’t changed after signing. It does not make you a trusted publisher: each workspace trusts your key explicitly.
Install and lifecycle
Trust the publisher
POST /v1/publishers/trust {"public_key": "<hex>", "label": "Quillfeather"}Install
POST /v1/packs/install (body: the pack JSON)
Creates a pack connection and
discoveredcapabilities namedpack:<pack_id>@<version>/<operationId>. Enable and invoke them like any HTTP capability. Every receipt carries the pack id, version and publisher.Upgrade, roll back, remove
POST /v1/packs/install?approve_permissions=true (a higher version that asks for more) POST /v1/packs/<pack_id>/rollback {"version": "0.1.0"} POST /v1/packs/<pack_id>/removeAn upgrade is compared with the currently active version. New hosts or effects need approval. Capabilities of the previous version are disabled. Removal stops future use. Old receipts stay exportable and verify offline.
Clarifications
x-ardyn-revision: "<Header-Name>" or an If-Match header parameter. Callers put expected_revision at the top level of the invoke request (not inside arguments). Ardyn sends it in that header, so a declared parameter with the same name is ignored as an argument.passive: false and include execute. A passive pack may not list execute.auth_methods must still be non-empty. Use ["api_credential"]. Credentials are attached only if the workspace gives the connection one.>=, <, = only. The runtime version is 1.0.0.manifest, bindings, permissions or files.Rejection codes
invalid_pack · unsafe_path · signature_invalid · publisher_untrusted · incompatible_runtime · invalid_manifest · binding_exceeds_permissions · permission_expansion_requires_approval · already_installed
Not supported: native binary packs on a hosted runtime, install hooks or server-side code, and webhook bindings inside packs (use the events method).