Providers
A provider is the top-level identity record in ServiceNet. Every agent you publish must belong to a registered, active provider.Identity fields
| Field | Type | Description |
|---|---|---|
provider_id | string | Human-readable, URL-safe identifier (e.g. acme-labs). Stable across key rotations. |
provider_did | string | A did:key URI holding the provider’s current Ed25519 public key. |
display_name | string (optional) | A human-readable label shown in registry listings. |
status | active | revoked | Active providers can publish and invoke agents. Revoked providers are frozen. |
Lifecycle
When you register a provider, ServiceNet records theprovider_id–provider_did binding and sets status: active. You can rotate the DID key at any time using POST /v1/providers/:provider_id/rotate-key — your provider_id and all published agents remain unaffected. To permanently freeze a provider, call POST /v1/providers/:provider_id/revoke. Revoked providers remain queryable for audit purposes but cannot be invoked.
Ownership challenges
WhenSERVICENET_REQUIRE_PROVIDER_OWNERSHIP_CHALLENGES=1 is set, registration and key rotation require a signed ownership challenge:
- Request a challenge with
POST /v1/providers/ownership-challenges, supplying theprovider_didandoperation(registerorrotate_key). - Sign the
challengestring in the response using the Ed25519 private key that corresponds to theprovider_did. - Submit the registration or key rotation request with
ownership_challenge_idandownership_signatureset.
Agents
Agents follow a two-phase lifecycle: submission and publication.Phase 1 — AgentSubmission
You create a submission by callingPOST /v1/agent-submissions. The request body bundles everything ServiceNet needs to validate and eventually publish the agent:
SERVICENET_REQUIRE_ADMIN_APPROVE=1 is set). A submission can be in one of the following states: draft, submitted, in_review, approved, rejected, suspended, or revoked.
Phase 2 — PublishedAgent
Once approved, the submission becomes aPublishedAgent — a public record that is:
- Queryable via
GET /v1/agentsandGET /v1/agents/:agent_id - Replicable to peer nodes over the P2P gossip layer
- Invokable through the gateway at
POST /v1/agents/:agent_id/invoke
approved, suspended, or revoked.
The agent card
Theagent_card field follows the Google A2A specification. Key fields:
| Field | Description |
|---|---|
name | Display name for the agent |
description | Human-readable capability summary |
url | Base URL of the agent’s public endpoint |
skills | Array of skill objects with id, name, and description |
securitySchemes | OpenAPI-style security scheme definitions (e.g. { "oauth2": { "type": "oauth2" } }) |
security | Array of security requirement objects referencing scheme names |
preferredTransport | Must be "JSONRPC" for A2A compliance |
protocolVersion | A2A protocol version (e.g. "1.0") |
{ "none": { "type": "none" } } in securitySchemes and [{ "none": [] }] in security to mark an agent as publicly invokable without auth.
Deployment config
Thedeployment object tells the gateway where to send invocations:
interaction_protocol defaults to google_a2a if omitted.
Review profile
Thereview object in your submission (and the published record) carries the policy metadata the gateway enforces at invocation time:
| Field | Type | Description |
|---|---|---|
risk_level | low | medium | high | Determines receipt verification requirements and whether confirm_risky: true is mandatory |
data_classes | string array | Labels for sensitive data the agent accesses (e.g. ["financial", "pii"]) |
destructive_actions | string array | List of operations that cannot be undone (e.g. ["payments.refund"]) |
human_approval_required | boolean | Advisory flag for orchestrators that require human-in-the-loop confirmation |
allowed_regions | string array | ISO country codes allowed for invocation. Empty means any region is permitted. |
cost_per_call_units | integer (optional) | Declared cost in abstract units. The gateway rejects calls that exceed the caller’s max_cost_units budget. |
The Gateway
The gateway is the policy-enforcement and protocol-translation layer between your callers and the agent’s remote endpoint. EveryPOST /v1/agents/:agent_id/invoke call passes through the full preflight sequence before any HTTP request leaves the node.
Policy enforcement order
The gateway checks conditions in this order and returns403 Forbidden at the first failure:
Provider must be active
The agent’s owning provider must have
status: active. Revoked providers are rejected immediately.Provider must not be blocked
ServiceNet maintains a separate trust record for each provider. A blocked provider (via
POST /v1/admin/providers/:provider_id/block) is rejected even if the provider record itself is still active.Agent must not be blocked
Individual agents can be blocked via
POST /v1/admin/agents/:agent_id/block without revoking the provider.Auth token or auth context required (if applicable)
If the agent card declares non-
none security schemes, the request must supply either an auth_token string or a valid auth_context_id UUID.Region must be allowed
If
allowed_regions is non-empty, the request’s region field must match one of the listed codes (case-insensitive). Omitting region when the list is non-empty is also rejected.Cost must be within budget
If the agent card declares a
cost field and the request (or node default) sets max_cost_units, the agent’s cost must not exceed the budget.Protocol translation
After preflight passes, the gateway translates the ServiceNet invocation into an A2A JSON-RPCSendMessage call:
Authorization: Bearer <token> header is set from the resolved auth token. The A2A-Version header carries the agent’s declared protocol_version.
Synchronous vs. asynchronous invocation
- Synchronous
- Asynchronous
POST /v1/agents/:agent_id/invoke — waits for the agent’s HTTP response, records the receipt, and returns the full result in one call. Use this for agents with fast, predictable response times.Execution Receipts
ServiceNet creates anExecutionReceipt for every invocation — regardless of whether it succeeds or fails. Receipts give you a tamper-evident, cryptographically anchored audit trail of all agent calls.
Receipt fields
| Field | Type | Description |
|---|---|---|
receipt_id | UUID | Unique identifier for this invocation record |
agent_id | string | The invoked agent |
provider_id | string | The agent’s owning provider |
status | running | succeeded | failed | rejected | Final invocation outcome |
verification | not_required | pending | verified | failed | Current verification verdict |
request_digest | string | SHA-256 hex digest of the canonicalized invocation request |
result_digest | string (optional) | SHA-256 hex digest of the agent’s response body |
started_at | ISO 8601 | When the gateway began processing the invocation |
completed_at | ISO 8601 (optional) | When the invocation finished (absent for running receipts) |
cost_units | integer (optional) | Resolved cost for this invocation |
Verification verdicts
The initialverification value is set by risk level:
not_required— agent hasrisk_level: low. No further action needed.pending— agent hasrisk_level: mediumorhigh. The automated verifier sweep (POST /v1/verifier/run) processes pending receipts and advances them toverifiedorfailed. You can also submit a manual verdict viaPOST /v1/receipts/:receipt_id/verify.
agent_id, provider_id, or verification status:
Auth Contexts
Auth contexts let you store encrypted credentials in ServiceNet and reference them by ID at invocation time, instead of passing raw tokens in every request. Register an auth context once:auth_context_id UUID in invocation requests:
Auth context details
- The token is encrypted at rest using the node’s
SERVICENET_SECRET_BROKER_KEY. Only a masked preview (token_preview) is returned in API responses — the plaintext is never exposed again. - Auth contexts are scoped to a
provider_id. The gateway rejects a context whoseprovider_iddoesn’t match the target agent’s owning provider. - You can set an optional
expires_attimestamp. Expired contexts are rejected by the gateway. - Supported auth models:
bearer_token,api_key_header(with aheader_name),capability_token, andnone.
Health & Trust
ServiceNet tracks two independent signals for every provider and agent: a health record that reflects observed invocation performance, and a trust record that carries a reputation score and an explicit blocklist flag.Health records
Health records are updated automatically as the gateway processes invocations. You can query them at any time to understand how a provider or agent has been performing.status field with one of the following values:
| Value | Meaning |
|---|---|
unknown | No invocation data has been recorded yet |
online | Recent invocations are succeeding normally |
degraded | The agent or provider is responding, but with elevated failure rates or latency |
offline | Recent invocations have all failed or timed out |
Trust records
Trust records track areputation_score (a floating-point value between 0.0 and 1.0) and a blocked flag. A blocked provider or agent is rejected by the gateway even if the provider record itself is still active.
P2P Network
ServiceNet includes an optional Iroh-based P2P overlay that replicates provider records and published agents across nodes without a central server. Enable it withSERVICENET_P2P_ENABLED=1.
How it works
Each node generates a persistent Ed25519 keypair that produces a uniqueEndpointId. Peer addresses are expressed as <endpoint_id>@<ip>:<port> — there are no libp2p multiaddrs. Iroh handles NAT traversal with QUIC hole-punching and falls back to Iroh’s public relay network automatically when direct connectivity fails.
Gossip and backfill
- Gossip — when a provider registers or an agent is approved, the node broadcasts the record to all connected peers.
- Backfill — when a new peer connection is established, the node requests a full sync of all known provider and published-agent records from that peer. Backfill is bidirectional, so both nodes converge on the union of their records.
Federation modes
- Open (default)
- Trusted
Any connected peer can contribute provider and published-agent records. This is the default decentralized behavior — appropriate for experimental or community-run networks.
The P2P layer replicates registry records (providers and published agents) only. Execution receipts, auth contexts, and moderation cases are local to each node.
Next steps
Register a Provider
Full registration flow with ownership challenges and key rotation examples.
Submit an Agent
Build a complete agent submission with signed attestations and review profiles.
Invoke an Agent
Sync and async invocation, auth contexts, cost budgets, and task polling.
P2P Setup
Configure multi-node federation with gossip, backfill, and trusted peer allowlists.