Harbor API reference
Harbor is the tenant-scoped intent-escrow service. It is the only component that writes to the provenance ledger or to Stripe/ACH settlement rails, and every state transition is signed and idempotent.
- Normative implementation:
crates/harbor-intent-escrow. - Public exposure: the Paybond Gateway exposes these routes under the
/harborprefix (for exampleGET /harbor/operator/v1/summary→ upstreamGET /operator/v1/summary). Inside the private VPC, service accounts may call Harbor directly. - Auth: Bearer JWT in
Authorization; tenant realm is the tokentidclaim. Kit SDKs mint the token from/v1/auth/harbor-access(see Authentication).
Route map
Intents
| Method | Path | Description |
|---|---|---|
POST | /intents | Create a principal-signed intent (binds to a predicate_dsl or predicate_ref). |
POST | /intents/{intent_id}/evidence | Submit payee-signed evidence; evaluates the intent predicate and returns a predicate_evaluation report. |
POST | /intents/{intent_id}/settlement/confirm | Confirms the release (or refund) transition after predicate evaluation. |
POST | /verify | Paybond Kit capability verification (PaybondCapabilityBinding). Validates capability_token against the intent row. |
Idempotency: POST /intents, POST /intents/{id}/evidence, and POST /intents/{id}/settlement/confirm honor the idempotency-key header. Wire shape: harbor-idempotency-openapi.yaml.
Predicate evaluation rules: harbor-predicate-dsl.md.
Operator console
Read-only views plus dispute lifecycle for the authenticated tenant's operator dashboard.
| Method | Path | Description |
|---|---|---|
GET | /operator/v1/summary | Tenant-scoped counts and totals (MetricPanel feed). |
GET | /operator/v1/intents | Paginated list with filters (status, operator, time window). |
GET | /operator/v1/intents/{id} | One intent with timeline and evidence rows. |
POST | /operator/v1/intents/{id}/dispute/open | Opens a dispute case; returns the case_id. |
POST | /operator/v1/intents/{id}/dispute/resolve | Resolves a dispute with an outcome (release/refund/split) and note. |
Gateway forwards these under /harbor/operator/v1/* with tenant/RBAC checks.
Ledger (read-only, PAYBOND-007)
| Method | Path | Description |
|---|---|---|
GET | /ledger/v1/tip | Current tip: sequence and entry commitment; empty when the tenant ledger has no rows yet. |
GET | /ledger/v1/authority | Hex-encoded Ed25519 verifying key for this Harbor deployment (offline signature checks). |
GET | /ledger/v1/events | Tenant-scoped append-only page. Query: after_seq (exclusive cursor, default 0), limit (1–256, default 64). |
GET | /ledger/v1/merkle/latest | Latest completed Merkle batch checkpoint JSON (checkpoint may be null); includes deterministic signature fields when Harbor can derive the signed checkpoint envelope. |
GET | /ledger/v1/verify | Tenant-scoped continuity verification result: signed row chain, closed-batch checkpoint coverage, and actionable failure guidance. |
GET | /ledger/v1/verifier-pack | Export the tenant’s self-contained continuity proof pack: signed ledger rows, signed checkpoints, witness freshness metadata, checkpoint-lineage witnesses, and observed signing-key epochs for offline reruns. |
POST | /ledger/v1/verifier-pack/verify | Re-verify an exported verifier pack without direct sled access. Fails closed on stale witness material, checkpoint witness drift, or key-transparency mismatches and returns the same verified/failed guidance contract as /ledger/v1/verify. |
Normative wire: harbor-openapi.yaml (Ledger tag). Ledger guarantees and append semantics: Ledger & provenance.
Policy registry (V1-006)
Versioned tenant policies built on top of the predicate VM. Complete OpenAPI: harbor-policy-openapi.yaml.
| Method | Path | Summary |
|---|---|---|
GET | /policy/v1/templates | List global policy template catalog (read-only, no tenant state). |
POST | /policy/v1/preview | Materialize DSL and human summary from { template_id, parameters } without persisting. |
POST | /policy/v1/test | Evaluate sample evidence against a materialized template (sandbox harness). |
GET | /policy/v1/versions?template_id=… | List tenant versions for one template. |
POST | /policy/v1/versions | Create a draft from { template_id, parameters }. |
GET | /policy/v1/versions/{template_id}/{seq} | Fetch one version row (state, materialized_dsl, content_digest_hex). |
POST | /policy/v1/versions/{template_id}/{seq}/publish | Publish an approved draft; updates tenant head for new intents. |
POST | /policy/v1/versions/{template_id}/{seq}/deprecate | Deprecate a version (must not be current head). |
POST | /policy/v1/versions/{template_id}/{seq}/retire | Retire a deprecated version. |
POST | /policy/v1/rollback | Move published head to a prior approved version. |
RBAC (enforced at Gateway):
- Read (
GET …/templates,GET …/versions,GET …/versions/{…}) — operator or tenant_admin. - Sandbox (
POST …/preview,POST …/test) — operator or tenant_admin. - Lifecycle mutations (
POST …/versions,POST …/rollback, publish/deprecate/retire) —tenant.adminentitlement only.
content_digest_hex on every version row is bound into intent signing v3, so rolling a version back is observable from any intent created after the switch.
Tenant isolation
Every row read or written by Harbor is filtered by the authenticated tenant realm. Harbor refuses to:
- Bind evidence from intent A to intent B across tenants.
- Redeem a capability token whose
tenant_idclaim differs from the session. - Append to the ledger without a signed tenant envelope.
See Tenant model for the full invariant matrix.