mirror of
https://github.com/Such-Software/adaptive-multi-protocol-gateway.git
synced 2026-10-17 07:31:32 +02:00
Add signed service manifest contract
This commit is contained in:
@@ -98,6 +98,13 @@ Fixture manifests are the AMPG-to-AMPB boundary. They declare the published URL,
|
||||
transport, logical context, and transport-context isolation result. They do not prescribe
|
||||
browser tabs, processes, or local daemon ownership; those decisions remain inside AMPB.
|
||||
|
||||
Signed service manifests are the service-to-client identity boundary. An application-owned
|
||||
route manifest supplies publication policy, while a service manifest represents approved public
|
||||
policy plus deployed transport addresses. AMPG currently validates manifests and calculates their
|
||||
digests; applications or hardened external signers own private-key operations. A shared service
|
||||
identity binds endpoints but never merges browser origins or transport contexts. See
|
||||
[Signed service manifests](service-manifests.md).
|
||||
|
||||
## Platform providers
|
||||
|
||||
Platform providers decide what daemon management means on the current host. AMPG detects
|
||||
|
||||
@@ -23,6 +23,10 @@ code. Generated artifacts are committed, then checked in CI by regenerating and
|
||||
: Generated from the route-manifest validator. App repos can use it to emit and validate
|
||||
`ampg.route-manifest.v1` without depending on AMPG internals.
|
||||
|
||||
`schemas/amp.service-manifest.v1.schema.json`
|
||||
: Generated from the signed service-manifest validator. Clients and applications can share
|
||||
the public identity, route, delegation, and signature contract without importing AMPG.
|
||||
|
||||
`openapi.json`
|
||||
: Generated if AMPG exposes a local control API for status, builds, plans, and daemon
|
||||
health.
|
||||
@@ -67,5 +71,6 @@ outside the public repo.
|
||||
- [ ] Generate daemon adapter docs from registered adapters.
|
||||
- [ ] Generate renderer docs from renderer defaults.
|
||||
- [ ] Generate route-manifest JSON Schema from code.
|
||||
- [ ] Generate service-manifest JSON Schema from code.
|
||||
- [ ] Commit generated artifacts.
|
||||
- [ ] Fail CI when regeneration produces a diff.
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
AMPG writes deterministic fixture manifests so AMPB can verify that generated site
|
||||
variants route to the expected browser transport context.
|
||||
|
||||
Fixture manifests are test contracts, not signed service discovery. See
|
||||
[Signed service manifests](service-manifests.md) for the client-facing identity and endpoint
|
||||
contract.
|
||||
|
||||
Current manifests use `ampg.fixture-manifest.v2`. The browser-facing `checks.context`
|
||||
field is a logical transport context and does not imply a separate browser profile or
|
||||
window.
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# Signed Service Manifests
|
||||
|
||||
> Status: draft | Updated 2026-07-11 | Applies to: AMPG service-manifest v1 consumers and producers
|
||||
|
||||
`amp.service-manifest.v1` binds one logical service identity to a bounded set of public
|
||||
transport endpoints. AMPG can validate, inspect, and calculate digests for these manifests.
|
||||
|
||||
A valid manifest proves that its signed endpoints were approved by the service key. It does
|
||||
not make different endpoints equivalent web origins. Browsers and clients must continue to
|
||||
isolate cookies, storage, credentials, cache, DNS, and connections by transport context.
|
||||
|
||||
A self-signed manifest does not bootstrap trust by itself. Clients must pin the service id or
|
||||
root key through an explicit import, trusted local configuration, QR code, or another authenticated
|
||||
discovery channel before accepting endpoint updates.
|
||||
|
||||
## Contract
|
||||
|
||||
The generated JSON Schema is
|
||||
[`schemas/amp.service-manifest.v1.schema.json`](../schemas/amp.service-manifest.v1.schema.json).
|
||||
A cross-language golden vector is available at
|
||||
[`tests/fixtures/amp.service-manifest.v1.golden.json`](../tests/fixtures/amp.service-manifest.v1.golden.json).
|
||||
A standalone signed example is available at
|
||||
[`examples/service-manifest.json`](../examples/service-manifest.json).
|
||||
|
||||
The signed payload contains:
|
||||
|
||||
- a service id derived from the root public key;
|
||||
- a display name and optional API contract digest;
|
||||
- one or more public transport endpoints;
|
||||
- an issue time, expiration time, and monotonic sequence;
|
||||
- an optional previous-manifest digest for update chaining.
|
||||
|
||||
Each route declares its transport, endpoint, matching transport context, maximum public
|
||||
interaction tier, priority, authentication methods, payment methods, and optional capability
|
||||
names. `internal` routes are invalid in a service manifest.
|
||||
|
||||
The optional delegation envelope lets an offline root key authorize a distinct online signing
|
||||
key for a bounded time. The service id remains derived from the root key.
|
||||
|
||||
## Canonical Bytes And Signatures
|
||||
|
||||
The v1 payload uses the [RFC 8785 JSON Canonicalization Scheme](https://www.rfc-editor.org/rfc/rfc8785.html)
|
||||
with an integer-only I-JSON profile. Floating-point values, duplicate object keys, lone Unicode
|
||||
surrogates, and integers outside the interoperable I-JSON range are rejected.
|
||||
|
||||
AMPG calculates the 32-byte payload digest with tagged SHA-256 using the tag
|
||||
`AMPG/service-manifest/v1`. The signature is a 64-byte
|
||||
[BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) Schnorr signature over
|
||||
that digest using a 32-byte x-only secp256k1 public key.
|
||||
|
||||
Service ids use tagged SHA-256 with `AMPG/service-id/v1`. Delegations use
|
||||
`AMPG/service-key-delegation/v1`.
|
||||
|
||||
AMPG implements dependency-free signature verification. It does not generate service private
|
||||
keys or sign operational manifests. Applications or a hardened external signer own private-key
|
||||
operations.
|
||||
|
||||
## Validation
|
||||
|
||||
```sh
|
||||
python3 -m ampg service-manifest validate service-manifest.json
|
||||
python3 -m ampg service-manifest validate service-manifest.json \
|
||||
--minimum-sequence 7 \
|
||||
--minimum-delegation-sequence 3 \
|
||||
--expected-previous "$PREVIOUS_DIGEST"
|
||||
python3 -m ampg service-manifest digest service-manifest.json
|
||||
python3 -m ampg service-manifest schema --output service-manifest.schema.json
|
||||
```
|
||||
|
||||
Validation checks strict JSON parsing, fields and bounds, service-id derivation, endpoint and
|
||||
transport compatibility, public-only interaction tiers, time validity, rollback constraints,
|
||||
delegation bindings, and BIP-340 signatures.
|
||||
|
||||
Manifest files are limited to 256 KiB. Consumers should persist the highest accepted manifest and
|
||||
delegation sequences per pinned service id and supply them during later validation.
|
||||
|
||||
`--at <RFC3339>` makes time checks reproducible. `--skip-time` is intended for fixture and
|
||||
forensic inspection; it does not disable structural or cryptographic checks.
|
||||
|
||||
## Manifest Boundaries
|
||||
|
||||
AMPG uses three separate contracts:
|
||||
|
||||
- `ampg.route-manifest.v1` is unsigned application-owned publication policy input.
|
||||
- `amp.service-manifest.v1` is signed public service identity and endpoint discovery.
|
||||
- `ampg.fixture-manifest.v2` contains expected routes for AMPG/AMPB compatibility tests.
|
||||
|
||||
The service manifest may contain public capabilities and a reviewed API contract digest. It
|
||||
must not contain deny rules, internal route names, upstream addresses, daemon keys, credentials,
|
||||
worker inventory, or deployment notes.
|
||||
|
||||
Clients should probe only the selected route or routes the user explicitly approves. Probing
|
||||
every advertised transport in parallel can correlate one client across networks.
|
||||
Reference in New Issue
Block a user