15. Public HTTP API
This chapter organizes the public HTTP APIs of OpenAgenet (OAN) into implementable and testable interface contracts. It covers the public and node-to-node calls of the official website backend, Registrar nodes, the Root platform, the content distribution platform, Discovery nodes, and the off-chain trust indexer. The paths, fields, and error semantics used by the browser, TypeScript SDK, and community skill package should remain consistent. Public APIs return only the materials required by public services; they do not return private keys, local identity backups, database administration capabilities, or access-statistics back-office data. An HTTP success response does not automatically mean that a resource has completed Root platform publication, network-wide distribution, or Discovery indexing.
15.1 API Conventions and Base URLs
| Contract item | Unified requirement | Failure behavior |
|---|---|---|
| Method and path | Follow the actual route declaration of the service | Return an identifiable route or method error |
| Media type | Use an explicit Content-Type for JSON requests and responses | Reject a body that cannot be parsed |
| Request ID | The client may provide one; the server generates one when absent | Keep the value consistent in the response and logs |
| Time | RFC 3339 strings | Do not silently convert an incorrectly formatted value |
| Caching | Set it according to data freshness and status | Expired data must carry a degradation indicator |
OAN interfaces transmit JSON using UTF-8. Time fields use RFC 3339 strings. DID, version, hash, and cursor values are handled as strings and should not be converted by clients into lossy numeric types. The base URLs for production environments are determined by deployment configuration. The protocol constrains paths and semantics, but does not make the current website domain a fixed condition for every deployment. Requests should carry a request ID that can run through one complete call chain. Responses should express results through stable machine-readable fields; presentation-layer text must not be used as the basis for program decisions.
15.1.1 Service Base Addresses
The current public backend address of the official website and the addresses of individual nodes are jointly determined by the frontend API configuration, node configuration, and deployment environment. The SDK provides independent endpoint configuration for Registrar nodes, Discovery nodes, the Root platform, and the content distribution platform. Callers must not assume that all services are deployed on the same host or under the same domain. Cross-node requests should also record the target node DID, so that the communication peer is not identified solely by a network address.
15.1.2 Path and Version Conventions
The version in a path should be expressed through an explicit path, protocol field, or capability negotiation. It must not be inferred from a page title or service name. When fields are added compatibly, clients should ignore unknown non-required fields. When field meaning, signature coverage, or status semantics change, the protocol version must be increased or a migration period must be provided. Interface paths, methods, and media types are part of the contract; clients must not guess based on differences in case or trailing slashes.
15.1.3 Request Authentication
Public queries and health interfaces may be accessed anonymously according to the deployment policy. Resource registration, node-to-node submission, and governance operations require, respectively, a resource control proof, node authorization materials, or operations authentication. Browser CORS permission only determines whether a page can read a response; it does not grant resource control. Authentication failures should return stable errors and should not hide permission problems behind an ambiguous 404 or an empty successful result.
15.1.4 Response Format
Successful responses should use JSON objects to express data, status, version, freshness, or source. Error responses should contain at least a machine-readable error code, a request ID, and necessary field locations. A service must not return an HTML error page where JSON is expected. For asynchronous publication and indexing, the response should clearly distinguish accepted, processing, completed, and failed states. An HTTP 200 response alone must not represent completion of the full chain.
15.2 Health, Readiness, and Service Status Endpoints
Health checks should distinguish process liveness, service readiness, availability of critical dependencies, and successful completion of business smoke tests. The website backend’s /health only indicates that the backend process can respond; it does not prove that the Registrar node, Discovery node, Root platform, or database is operating normally. After an operations deployment, node health, database connectivity, indexer synchronization status, and the minimum registration and Discovery business paths should be checked separately. Public status interfaces should not disclose internal connection strings, tokens, or stack traces.
15.3 Registrar Node Registration Endpoints
| Request stage | Must be verified | A success response does not mean |
|---|---|---|
| Draft validation | Local identity, required fields, DID Document, and metadata | Submitted or published |
| Resource submission | Control proof, node authorization, and resource package digest | Root platform publication completed |
| Status query | Registration, publication, distribution, and indexing stages | All nodes have converged |
| VC retrieval | Issuer, subject, version, digest, and status | A guarantee of resource business quality |
| Same-DID update | Original control relationship, preceding version, and new digest | Automatic acquisition of update authority |
The reference implementation accepts both POST /resources/register and the compatibility entry point POST /resources/submit; both enter the same resource registration handler. The browser or SDK generates the resource DID, DID Document, metadata, version, and digest locally, and submits them as a ResourceRegistrationSubmission. Private keys and local identity backups are not part of the request body. The Registrar node first checks the structure, resource type, authorization domain, and subject control proof, and then calls the Root platform’s verification and publication endpoint with a signed upstream request.
The core fields of a successful response are as follows. The example values are provided only to explain the structure:
{
"status": "submitted",
"resourceDid": "did:oan:SKLG:example",
"resourceType": "skill",
"registrationCredential": {},
"rootResponse": {}
}
status: submitted means that the Registrar node has completed its processing of this request and obtained a Root platform response. It does not mean that content distribution and indexing by all Discovery nodes have completed. The reference implementation issues and returns registrationCredential; the client should still allow the credential field to be empty or unparseable while preserving the submission result and original response, so that “registration failed” can be distinguished from “credential missing.” GET /resources, GET /resources/{did}, GET /registrar/status, and GET /registrar/stats are used to read registration records and node status, but the public scope is still determined by the deployed reverse proxy and access policy.
15.4 Root Platform Publication and Status Endpoints
The Root platform separates public read routes from management write routes. The resource publication entry point is POST /root/resources/verify-and-publish, called by a Registrar node with upstreamAuth. The Root platform re-verifies the source node identity, node authorization, resource DID, DID Document, digest, and control proof. Resource queries use GET /root/resources/{did}. The historical version list and a specified version use /root/resources/{did}/versions and /root/resources/{did}/versions/{version}, respectively.
| Interface category | Typical path | Main boundary |
|---|---|---|
| Root platform identity and status | /root/did, /root/status |
Provides public identity or runtime summaries; does not expose management capabilities |
| Resource reads | /root/resources/{did} and version paths |
Returns saved resource versions and publication materials |
| Publication writes | /root/resources/verify-and-publish |
Requires a trusted upstream envelope from a Registrar node |
| Publication queues | /root/queues/cdn-publish, /root/queues/discovery-notify |
Used to observe asynchronous propagation; whether they are public depends on the deployment policy |
| Governance management | Authorization, domain-update, and revocation paths | Management routes that require separate administrator authentication |
A successful publication response means that the Root platform accepted and saved a compliant resource version. The content distribution publisher and Discovery notification tasks then continue processing it. Callers should confirm propagation progress through the resource version, publication queue, or subsequent status, and must not interpret one 2xx response from the Root platform as network-wide visibility.
15.5 Content Distribution Endpoints
The content distribution platform provides single-resource reads, batch reads, incremental indexing, and split-material reads. GET /cdn/resources/{did} returns a resource package. POST /cdn/resources/batch-get reads multiple resources by DID. GET /cdn/documents/{did} and GET /cdn/metadata/{did} return the DID Document and metadata, respectively. Catalog interfaces are located under /cdn/catalog/.... The Root platform publisher writes through the protected POST /cdn/resources or POST /cdn/resources/batch. POST /cdn/purge is a management operation and should not be exposed as a public write interface.
Incremental synchronization uses GET /cdn/resources/index?afterCursor=<n>&limit=<n>. In the current reference implementation, omitting parameters may return a compatibility format; supplying cursor or quantity parameters returns a structured page:
{
"items": [],
"count": 0,
"afterCursor": 42,
"nextCursor": 42,
"hasMore": false
}
A Discovery node should save nextCursor only after fully validating the resource packages in the batch; it must not advance the cursor early merely because the HTTP request succeeded. The current service imposes an implementation-level body limit on batch publication requests. This is a deployment safeguard of the reference implementation, not a protocol value permanently fixed for every OAN node.
15.6 Discovery Query and Resource Detail Endpoints
| Query result field | Purpose | Freshness or trust boundary |
|---|---|---|
| resourceDid | Precisely identifies the resource | Still requires resolution and control verification |
| resourceType/version | Filtering and version selection | Does not replace publication proof |
| sourceNode | Tracks the result source | Node authorization requires a separate check |
| indexedAt/cursor | Determines index freshness | Does not equal on-chain finality |
| matchExplanation | Explains a semantic match | Does not equal invocation authorization |
The Discovery query entry point is POST /discovery/resources/query. The request may contain a natural-language description, resource type, capability tags, protocol, version, version mode, and quantity limit. If the query text can be recognized as a complete resource DID, the reference implementation prioritizes an exact-DID query. Otherwise, it prioritizes an available semantic index and falls back to a keyword-candidate flow when the semantic backend is unavailable or produces no result. discoveryDid in the response identifies the Discovery node that returned the results. createdAt identifies when the response was generated, and a candidate’s score expresses only retrieval relevance.
{
"query": "I need a tool that can search code repositories and summarize the project structure.",
"resourceType": "skill",
"capabilityTags": [],
"versionMode": "latest",
"limit": 10
}
Indexed-resource reads and diagnostic interfaces include /discovery/index/resources, /discovery/index/resources/{did}, /discovery/index/stats, and /discovery/query/stats. Whether these are exposed to the Internet should be determined by the deployment exposure policy. An empty candidate array is a valid query result and should not be converted into a network error. Semantic-backend fallback, index lag, or snapshot degradation should be reflected in observable information; duplicate candidates must not be manufactured to hide differences between data sources.
15.7 DID Resolution Endpoints
Infrastructure nodes return their own DID Documents through GET /registrar/did, GET /root/did, and GET /discovery/did, respectively. A resource DID can be resolved through the Root platform resource detail, the content distribution platform’s /cdn/documents/{did}, or the detail of a resource already indexed by a Discovery node. The appropriate choice depends on whether the caller needs the authoritative saved version, a distributed copy, or a Discovery read model.
The id in a resolution response should exactly match the requested DID and preserve public verification methods, verification relationships, service endpoints, and OAN metadata. Clients need to distinguish three types of result: an invalid DID format is a request problem, a nonexistent resource is an absent record, and temporary unavailability of a dependency or node is a recoverable failure. No resolution path should return a browser local identity backup, private key, or server key file.
15.8 VC and Proof Retrieval Endpoints
Registration VCs, node authorization VCs, and Root proofs of trusted publication cover different facts. A Registrar node stores registrationCredential in the successful registration response and resource record. The Root platform may return the resource package and its Root proof through resource detail and version interfaces. The /.../root-authorization status interfaces of Registrar nodes and Discovery nodes expose the authorization materials or verification status observed by the respective node. The Root platform’s infrastructure-authorization VC issuance entry point is a protected operation and should not be treated as an anonymous self-service retrieval interface.
| Evidence | What it proves | What must still be checked after retrieval |
|---|---|---|
| Registration VC | A particular Registrar node processed a particular resource registration | Issuer, subject, resource digest, signature, and status |
| Node authorization VC | An infrastructure node was granted a role and authorization domain | Issuer, node DID, role, validity period, and revocation status |
| Root proof of trusted publication | A particular resource version and digest were accepted by the Root platform | Resource DID, version, digest, signature, and governance status |
Returning a credential object from an interface does not mean that the credential has been verified. The caller should resolve the issuer’s public key according to proof.verificationMethod and check credential time and governance status. When status cannot be obtained, the caller should explicitly return “indeterminate” or tighten high-risk operations rather than assuming validity.
15.9 Governance Status and Event Endpoints
The Root platform provides infrastructure node directories through /root/registrars, /root/discovery-nodes, and their DID detail interfaces. It provides a governance-event read model through /root/bulletin/events and /root/bulletin/events/{sequence}. Registrar nodes and Discovery nodes expose the authorization status observed by each node through /registrar/root-authorization and /discovery/root-authorization, respectively. A Discovery node also expresses its current authorization domain through /discovery/authorized-domains.
The off-chain trust indexer’s data is an off-chain projection of on-chain governance facts. Status responses should carry the latest sequence, observation time, or synchronization position so that callers can assess freshness. The Root platform’s authorization, authorization-domain update, and revocation interfaces are management routes and require administrator authentication. If on-chain reads fail, the index sequence does not increase for an extended period, or local state cannot be confirmed, the Root platform and Discovery nodes should mark results as stale or indeterminate and tighten publication, synchronization, or Discovery-visibility decisions.
15.10 Metrics and Observability Endpoints
The website backend organizes multiple nodes and data sources through public read interfaces such as /api/public/home/summary, /api/public/network/summary, /api/public/network/governance-events, node directories, and node statistics. Node-side interfaces also include /registrar/stats, /discovery/index/stats, /discovery/query/stats, and /cdn/catalog/resources/stats. The website aggregation is a display read model and should not be treated as a replacement for the authoritative raw status of each node.
Metric fields should provide the generation time, statistical window, source, and missing-data status together. Windows such as TODAY, THIS WEEK, and THIS MONTH require a common time zone and explicit start and end boundaries. The cumulative resource count must not be confused with the number of additions within a window. Public interfaces return only necessary aggregate information. Access-statistics details, complete logs, database paths, management tokens, and internal error stacks remain operations data. The internal reporting entry point used by nodes to report statistics to the website should have authentication and exposure boundaries independent from public read interfaces.
15.11 Request and Response Models
Requests and responses should be able to express at least four results: success, processing, failure, and indeterminate:
status = accepted | processing | completed | failed | unknown
requestId = used to trace one call across nodes
Clients must determine asynchronous stages from machine-readable status and must not infer that publication, distribution, and Discovery indexing have completed from HTTP 200 or page text alone.
Request and response models are stable boundaries for interface fields, statuses, and errors. Field presence, types, enumerations, hash algorithms, time formats, DID syntax, and nesting relationships should be consistent with oan-protocol-common and the actual node types. Handling of unknown fields should be determined by the protocol version. Missing required fields, duplicate fields, empty values, and incompatible versions should produce errors that can be located.
The actual type relationships of the core node interfaces are as follows. Value in the table means that the current handler returns dynamic JSON; it does not mean that every field forms a stable contract. Specific fields still need to be checked against the corresponding handler, shared structures, and error tests.
| Service | Method and path | Input type | Output type or stable fields |
|---|---|---|---|
| Registrar node | POST /resources/register, POST /resources/submit |
ResourceRegistrationSubmission |
Value: status, resourceDid, resourceType, registrationCredential, rootResponse |
| Root platform | POST /root/resources/verify-and-publish |
ResourceVerifyAndPublishRequest |
Value: verification queue status, resource version, three hashes, lifecycle, and CDN queue status |
| Content distribution platform | POST /cdn/resources, POST /cdn/resources/batch |
ResourceCdnPublishRequest, ResourceCdnBatchPublishRequest |
Value: publication status, cursor, and batch accepted/failed items |
| Content distribution platform | GET /cdn/resources/{did} |
Path parameter did |
ResourcePackage |
| Discovery node | POST /discovery/resources/query |
ResourceDiscoveryQuery |
ResourceDiscoveryResponse |
| Off-chain trust indexer | GET /v1/status, GET /v1/events |
Optional limit query parameter |
Dynamic status JSON; the event response contains an events array |
The business stage of an interface cannot be inferred only from the HTTP status code. When a Registrar node returns submitted, the registration record has been written. When the Root platform returns resource-verified-and-queued, the resource has passed the Root platform’s current verification and entered the distribution queue. When the content distribution platform returns published, the resource package has been written to the distribution platform. When a Discovery response returns candidates, it only means that the current Discovery node’s index can see them. Callers still need to make subsequent judgments using the resource DID, version, hashes, Root proof, governance status, and freshness.
15.11.1 Registration Requests and Responses
A registration request must associate the resource DID, DID Document, resource type, metadata, resource package, version, hashes, Registrar node, and control proof. Before signature verification, the server should confirm the request path, target, challenge, nonce, and content digest; only after verification should it perform duplicate checks and writes. The response should separately express registration acceptance, the registration VC, the Root platform submission result, and retryable errors. It must not make the client infer completion of all stages from a single “success” message.
The reference implementation’s public registration entry point directly accepts ResourceRegistrationSubmission. When a Registrar node forwards the request to the Root platform, it constructs a ResourceVerifyAndPublishRequest and binds the method, path, target, time, nonce, and business-body digest in upstreamAuth. The browser submits only resource materials and a control proof; it should not construct or hold the upstream signing identity of an infrastructure node.
15.11.2 Publication Requests and Responses
A publication request must associate the Registrar node source, resource version, resource package digest, DID Document hash, metadata hash, authorization materials, and request ID. The publication response should carry a Root proof of trusted publication or clearly state that it has not yet been produced, and should return a publication status, batch reference, or cursor reference. Hash mismatches, an unauthorized node, an invalid control proof, and temporary dependency unavailability should be distinguished as non-retryable and retryable failures.
When the Root platform submits to the content distribution platform, single-item and batch requests use ResourceCdnPublishRequest and ResourceCdnBatchPublishRequest, respectively. Batch items are associated with the Root platform publication order through publicationCursor. The accepted count, failed items, or completion cursor in the response is used to resume a publication task; it does not mean that a Discovery node has completed indexing.
15.11.3 Discovery Requests and Responses
A Discovery request may use a resource DID, resource type, capability tags, protocol, authorization domain, lifecycle, keywords, or a natural-language task description. The response should return candidate DIDs, versions, resource types, match explanations, the source Discovery node, index version, governance status, and proof references. A pagination cursor must be bound to the query conditions and the ordering snapshot. An empty result is not an interface failure; service unavailability, index lag, and snapshot degradation should be clearly marked.
The current ResourceDiscoveryResponse contains discoveryDid, candidates, createdAt, and an optional proof. A candidate contains the resource DID, resource type, score, version, lifecycle, capability tags, authorization domain, service endpoints, protocol bindings, resource-package information, and Root proof, among other fields. When an optional field is absent, the client must not use presentation-layer default text to fabricate a trusted fact.
15.11.4 Status and Error Responses
Status and error responses use HTTP status codes for coarse-grained results, JSON error codes for business reasons, and requestId for trace correlation. An error may contain a field path, retryability, recommended wait time, and current processing status, but must not echo private keys, complete control proofs, or internal exception stacks. The client should retain the original error for auditing while giving the user an explanation appropriate to its sensitivity.
The current error bodies of multiple Rust nodes use the concise structure {"error":"machine_readable_reason"}, with the HTTP status code distinguishing request errors, permission errors, or service errors. Not every existing response contains requestId, a field path, and retry guidance. These fields are therefore directions for interface consistency, and callers must not assume that every node currently returns a complete error envelope.
15.12 HTTP Status Codes and Common Errors
| Status | Typical meaning | Client action |
|---|---|---|
| 400 | Invalid request format or field | Correct the input and retry |
| 401/403 | Identity or authorization requirements are not met | Do not retry blindly; check the credential and authorization domain |
| 404 | Resource or route does not exist | Distinguish an unknown resource from a path error |
| 409 | DID, version, or idempotency conflict | Query the current status before deciding whether to update |
| 429 | Rate or concurrency limit exceeded | Retry according to Retry-After or a backoff policy |
| 5xx/timeout | Service or dependency failure | Retry a limited number of times while preserving the request ID |
It is recommended that 2xx indicate that the request was processed according to the interface semantics, 4xx indicate that the request, authentication, authorization, or business preconditions were not satisfied, and 5xx indicate a server-side or dependency failure. 202 Accepted can indicate only that an asynchronous task has been accepted; it cannot indicate that publication is complete. 409 Conflict can be used for a same-DID version conflict or a duplicate state that requires client confirmation. 429 Too Many Requests should be accompanied by rate-limit information. Services should avoid returning arbitrary different status codes for the same business reason.
The client should first inspect the HTTP status and then parse error or the business status in the JSON. A connection failure, TLS failure, or browser CORS rejection has no usable HTTP response and must not uniformly be displayed as “the server returned 500.” Sending POST to an endpoint that supports only GET normally produces 405 Method Not Allowed at the routing layer; the method and reverse-proxy forwarding rules should be checked first.
15.13 Rate Limits, Caching, and Security Headers
| Control | Public queries | Registration or node-to-node requests |
|---|---|---|
| Rate | May be limited by source and interface | Should consider subject, node, and idempotency key |
| Request size | Limit query descriptions and page sizes | Limit resource packages and batch sizes |
| Caching | Allow read-only caches with freshness information | Do not cache results that change authorization decisions |
| Security headers | TLS, CORS, and necessary security headers | Add authentication and source verification |
Rate limiting should consider at least the source IP, authenticated subject, node DID, resource DID, and interface category, and should use different quotas for registration, Discovery, synchronization, and health requests. Read-only public queries may use short-lived caches, but DID Documents, VCs, Root proofs, governance status, and Discovery results must carry a version or freshness boundary. A conditional request’s ETag must correspond to the response content version. Security headers, content-type checks, and response-body size limits should be enforced at the gateway or service layer. Cache testing should at least verify the following: the first request obtains data and freshness information; a conditional request does not return an incorrect version; after governance revocation, an old cache does not continue authorizing writes; and when the backend is unavailable, an old snapshot is clearly marked rather than disguised as a real-time result. Write interfaces and signed requests should not be stored by a shared cache.
Request-body limits, query-count boundaries, and CORS configuration in the current node code provide the first layer of protection. Production deployment also requires the reverse proxy to handle connection counts, rates, timeouts, and request-size limits.
15.14 CORS, Browser Clients, and Cross-Origin Policy
When a browser calls a node API, the server should allow only the necessary official website origins, methods, and request headers. A preflight request must not broaden business authorization. Access-Control-Allow-Origin: * must not be used together with credentials to transmit sensitive materials. Public cross-origin reads by the official website and node-to-node authentication are two separate controls: the former serves the browser security model, while the latter verifies the request subject and permissions. CORS changes should be a deployment check item to prevent the frontend from producing an opaque Failed to fetch error.
Registrar nodes, Discovery nodes, and the content distribution platform all construct their CORS layer from configuration. The website backend preferentially uses the configured frontend origin and falls back to a more permissive policy only when the configuration value cannot be parsed. Production environments should avoid triggering this fallback branch and should perform registration, Discovery, and preflight smoke tests from both Chinese and English pages after deployment. When a browser displays Failed to fetch, check the request URL, HTTPS mixed content, certificate, DNS, reverse proxy, preflight response, and allowed origins in sequence; do not inspect only the backend business logs.
15.15 Boundary Between Public Endpoints and Operations-Only Endpoints
The public boundary is divided into “public reads, resource-controller signatures, node-to-node authorization, and operations-only” categories. Public interfaces may provide health information, public catalogs, published resources, and limited metrics. Resource-controller interfaces receive a control proof but not a private key. Node-to-node interfaces require node identity, authorization VCs, and request signatures. Operations interfaces are exposed only within a controlled network or authentication boundary. Access-statistics data may be read only by back-office or operations-authorized subjects; ordinary visitors must not query details through the website or public APIs.
15.15.1 Public Query Interfaces
Public query interfaces include public catalogs, Discovery queries, published resource details, public DID Documents, public proofs, and health information. Returned data should be filtered by a field allowlist, hiding local file paths, private endpoints, database-management fields, and unpublished credentials. Public queries must still observe lifecycle, governance filtering, and authorization-domain visibility; anonymous access must not bypass these decisions.
The website’s /api/public/... routes mainly provide aggregated display data and do not mean that all node routes are automatically public. Deployment should establish an allowlist of public paths and verify that anonymous access can read only filtered data. POST /api/public/site-analytics/visit, which records page visits, is a one-way collection entry point and does not provide an interface for reading statistical details.
15.15.2 Node-to-Node Interfaces
Node-to-node interfaces support cooperation among Registrar nodes, the Root platform, the content distribution platform, Discovery nodes, and the off-chain trust indexer. Requests should carry the source and target identities, authorization materials, protocol version, request ID, time window, nonce, content digest, and signature. Node-to-node interfaces should not be called directly by the website browser in place of a node; browser resource submissions should pass through the Registrar node’s public entry point and server-side validation.
Typical node-to-node writes include a Registrar node calling /root/resources/verify-and-publish, the Root platform publisher calling /cdn/resources/batch, and the Root platform sending authorization-scoped synchronization notifications to Discovery nodes. Even when a path is reachable from the Internet, the receiver must still verify the trusted upstream envelope and node authorization; network reachability itself is not an authorization basis.
15.15.3 Operations Interfaces
Operations interfaces include deployment status, internal diagnostics, access-statistics details, database administration, key rotation, and recovery operations. They must not appear in the public API catalog or browser-side code, and should use separate authentication, least privilege, audit logs, and network isolation. Errors returned by operations interfaces must not be fully passed through a public proxy to ordinary users.
The Root platform’s authorization, revocation, and publication-management routes, as well as the website’s internal node-statistics reporting entry point, should be separated from public read routes at the reverse-proxy layer. Combining routes in the same process in service code does not mean that they should share the same Internet exposure policy. Operations personnel should check application authentication and proxy path allowlists together.
15.15.4 Access Control and Exposure Boundaries
Access control should check the route, method, authenticated subject, node role, authorization domain, and resource scope together. Exposure boundaries should be enforced through ports, the reverse proxy, and CORS configuration. Before publication, four identities should be used to test allowed and denied paths separately: an anonymous browser, a resource controller, an unauthorized node, and an operations subject. The test should preserve status codes, response fields, and log-correlation evidence.
| Test identity | Typical operations that should be allowed | Typical operations that should be denied |
|---|---|---|
| Anonymous visitor | Health, public catalogs, Discovery, and public resource reads | Authorization, revocation, database and statistical-detail reads |
| Resource controller | Submit a resource with a valid control proof | Submit a same-DID update not controlled by the subject |
| Authorized node | Perform node-to-node calls within its role and authorization domain | Access management operations belonging to another role |
| Operations subject | Perform management and diagnostics under separate authentication | Bypass auditing or obtain a business subject’s private key |
15.16 API Examples and Machine-Readable Interface Descriptions
openapi: 3.1.0
info:
title: OAN Agent Contract
version: 0.1.0
paths: {}
The example above is the actual skeleton of oan-protocol-common/schemas/agent-contract/openapi.yaml. It identifies the OpenAPI version and contract-file version, but paths is still empty. Therefore, it can serve only as a machine-readable contract entry point and must not be treated as a complete description of all public and node-to-node APIs. Interface verification should use the Router definitions of each service, shared protocol structures, configuration, and deployment proxy rules together.
The minimum executable example for a user should begin with a health or public query that requires no signature. The hostname in the following command is a placeholder:
curl --fail-with-body \
--header "Accept: application/json" \
"https://registrar.example/health"
Examples that write to the registration service, Root platform, or content distribution platform require a real DID, digest, control proof, or node-to-node signed envelope. A static fake signature must not be presented as an executable request. When the OpenAPI description is further developed, methods, request bodies, responses, authentication, errors, and examples should be completed route by route, and automated tests should check whether the description remains synchronized with the actual routes.
References
| Source | Type | Link |
|---|---|---|
oan-protocol-common |
Code repository: HTTP payloads, error codes, and OpenAPI contract entry point | https://github.com/wolfbrother/oan-protocol-common |
oan-root-services |
Code repository: Root platform public and internal APIs | https://github.com/OpenAgenet/oan-root-services |
oan-registrar-node |
Code repository: Registrar service APIs | https://github.com/OpenAgenet/oan-registrar-node |
oan-discovery-node |
Code repository: Discovery service APIs | https://github.com/OpenAgenet/oan-discovery-node |
oan-sdk-ts |
Code repository: Client HTTP calls and type wrappers | https://github.com/OpenAgenet/oan-sdk-ts |
| OAN Resource Identity and Discovery | IETF draft: resource identity and Discovery interface direction | https://datatracker.ietf.org/doc/draft-xu-oan-resource-identity-discovery/ |
| Efficient Agent Discovery Profile | IETF draft: Discovery query profile | https://datatracker.ietf.org/doc/draft-xu-efficient-agent-discovery-profile/ |