5.6 KiB
Capability Spec Delta: network-plugin-auth (complete-network-plugins)
Package: @suaveplan/network-plugin-auth
Status: PROPOSED
Every requirement below carries a
**Verified by:**line at authoring time. This is the first canonical capability spec for the package; the delta is entirely## ADDED Requirements.
ADDED Requirements
Requirement: MeshMembershipVerifier verifies join requests against an AuthProvider
The package SHALL export MeshMembershipVerifier, MeshMembershipVerifierConfig, JoinRequest, JoinResult, AuthProvider, and a Capability union enumerating the recognised mesh capabilities. The verifier SHALL delegate credential verification to the supplied AuthProvider and SHALL throw MeshAuthError(JOIN_REJECTED) when the provider denies the request.
Scenario: provider denies the join
- WHEN
verifier.verify(request)is called and the provider returns a denial - THEN the call throws
MeshAuthErrorwithcode === "NET_AUTH.JOIN_REJECTED"
Verified by: src/verifier/verifier.spec-conformance.test.ts::"throws JOIN_REJECTED when provider denies request"
Requirement: CapabilityTokenIssuer mints signed capability-bound tokens
The package SHALL export CapabilityTokenIssuer, CapabilityTokenIssuerConfig, CapabilityToken, and a TokenSigner interface. Issued tokens SHALL embed the granted capability set, an issuance timestamp, and an expiry; signature SHALL be produced by the supplied TokenSigner.
Scenario: issued token carries capability set and expiry
- WHEN
issuer.issue({ subject, capabilities, ttlMs })is called - THEN the returned
CapabilityTokenhas the same capabilities, aniat, anexp = iat + ttlMs, and a signature produced by the supplied signer
Verified by: src/issuer/issuer.spec-conformance.test.ts::"issued token carries capability set and expiry"
Requirement: CapabilityTokenIssuer rejects expired and tampered tokens on verify
The issuer SHALL expose a verify(token) operation that throws MeshAuthError(TOKEN_EXPIRED) when the current clock exceeds token.exp and MeshAuthError(TOKEN_INVALID_SIGNATURE) when the signature does not validate against the configured key.
Scenario: expired token
- WHEN
verify(token)is called afterclock() > token.exp - THEN the call throws
MeshAuthError(TOKEN_EXPIRED)
Scenario: tampered signature
- WHEN
verify(token)is called on a token whose payload was modified after signing - THEN the call throws
MeshAuthError(TOKEN_INVALID_SIGNATURE)
Verified by: src/issuer/issuer.spec-conformance.test.ts::"throws TOKEN_EXPIRED past exp" AND src/issuer/issuer.spec-conformance.test.ts::"throws TOKEN_INVALID_SIGNATURE on tampered payload"
Requirement: CrossMeshTrustValidator gates cross-mesh relay authority
The package SHALL export CrossMeshTrustValidator, CrossMeshTrustValidatorConfig, TrustRelation, and the TrustDirection union "relay" | "backbone". The validator SHALL reject relay attempts between meshes lacking a registered TrustRelation and SHALL throw MeshAuthError(TRUST_NOT_ESTABLISHED) on failure.
Scenario: relay attempt without trust
- WHEN
validator.authorize({ sourceMesh, targetMesh, direction: "relay" })is called with no registered relation - THEN the call throws
MeshAuthError(TRUST_NOT_ESTABLISHED)
Verified by: src/trust/trust-validator.spec-conformance.test.ts::"throws TRUST_NOT_ESTABLISHED when no relation registered"
Requirement: Capability enforcement raises CAPABILITY_DENIED on insufficient grant
The verifier SHALL throw MeshAuthError(CAPABILITY_DENIED) when a request requires a capability that the supplied token does not carry.
Scenario: missing capability
- WHEN a request requires
"relay-egress"and the token grants only["mesh-join"] - THEN the call throws
MeshAuthError(CAPABILITY_DENIED)withcontext.required === "relay-egress"
Verified by: src/verifier/verifier.spec-conformance.test.ts::"throws CAPABILITY_DENIED on missing capability"
Requirement: Error-code registry is frozen and namespaced NET_AUTH
MESH_AUTH_CODES SHALL be frozen under the NET_AUTH namespace and SHALL include exactly: JOIN_REJECTED, TOKEN_EXPIRED, TOKEN_INVALID_SIGNATURE, CAPABILITY_DENIED, TRUST_NOT_ESTABLISHED. Every code SHALL be reachable from a production throw site.
Scenario: registry membership
- WHEN
MESH_AUTH_CODESis inspected - THEN every key maps to a value of the form
"NET_AUTH.<KEY>"and no extra keys are present
Verified by: src/error-codes.spec-conformance.test.ts::"MESH_AUTH_CODES is frozen and prefixed NET_AUTH"
Requirement: No bare-Error throws in production code
src/ SHALL contain zero bare throw new (Error|TypeError|RangeError|SyntaxError)\( sites outside test files. Every production failure throws MeshAuthError or a transitive SuaveplanError subclass.
Scenario: source grep returns zero hits
- WHEN the grep is run
- THEN the output is empty
Verified by: tests/no-bare-throws.test.ts::"network-plugin-auth src/ has no bare Error throws"
Requirement: README is auto-docs idempotent
The package README.md SHALL contain exactly one balanced auto-docs block; the generator SHALL produce a byte-identical file on a second run.
Scenario: marker count is exactly one
- WHEN
grep -c "begin:auto-docs" packages/network/network-plugin-auth/README.md - THEN output is
1
Verified by: scripts/generate-package-module-tree.test.ts::"README regen is idempotent for network-plugin-auth"