HPPR Ring2 Group Authentication
Tags: repo, auth
© R.A.Sol
Ring2 is group-based authentication. Signer authorization is based on membership in the target group. Ring2 requests use the Ring2 session envelope defined in 042.
Request Envelope
Ring2 uses:
Group: <target-group>
API: 🖧<COMMAND>
Key: <repo-name>/<session-id>
Seal-By: <member-verifier>
Rules:
Groupis the target group, notrepo.APInames the protocol command.Keycarries repo name and HELLO session.Seal-Bymust resolve to group membership.- non-members follow a distinct runtime identity path where
command semantics permit unauthenticated fallback; that path
evaluates under
anyonepolicy.
Packet Families
Ring2 auth, membership, and policy are in separate packet families.
Auth Config
Coordinate:
//<group>/admin/ring2//auth/|/seal/<repo-verifier>
Signed by repo verifier.
Required:
Ring2-Name— must match coordinate<group>, appears exactly once
Optional:
Ring2-Expire— appears at most once
Validation:
- coordinate
<group>must matchRing2-Name Memberheaders are invalid hereMember-Delegateheaders are invalid hereACL-Ruleheaders are invalid here
Members
Coordinate:
//<group>/admin/members//root/|/seal/<verifier>
Multiple packets may exist under different signers and versions.
Required (at least one of):
Member(repeatable)Member-Delegate(repeatable)
Validation:
- at least one
MemberorMember-Delegateheader required ACL-Ruleheaders are invalid here- auth-config headers (
Ring2-Name,Ring2-Expire) are invalid here
Policy
Coordinate:
//<group>/admin/ring2//policy/|/seal/<repo-verifier>
Signed by repo verifier.
Required:
ACL-Rule(repeatable) — at least one required
Validation:
Memberheaders are invalid hereMember-Delegateheaders are invalid here- auth-config headers are invalid here
ACL-Rule format and evaluation are defined in 050. Each ACL-Rule coordinate
must start with //<group>/.
Adhoc Member Verifiers
Clients MAY derive a Ring2 member verifier locally from:
- group
- username
- password
Rules:
- username MUST satisfy one
Keysegment’s constraints - derivation is fully client-local and does not depend on HELLO
- repo MUST NOT receive or store the password
- identity text form is
ring2:<group>/<username>|<password> - parser split rule is first
| - derivation input bytes are exactly
<group>/<username>|<password> - Argon2id uses fixed built-in client parameters:
m=12288,t=3,p=1 - Argon2id salt is the first 16 bytes of
BLAKE3.derive_key("hppr-🖧/ring2-phc-salt", "<group>/<username>|<password>") - Argon2id output is encoded as
V.<b64a>.H3 - signing secret derivation input is:
<derived-token>/<group>/<username>|<password> - the resulting verifier is stored as an ordinary
Member
Contextual form:
ring2:/<username>|<password>resolves group from request context- derivation input bytes are exactly
<resolved-group>/<username>|<password> - text form with empty group is reserved for this convention
This is a client-side derivation convention only. Server behavior is unchanged.
Membership Config Detail
Supported headers in member packets:
Member
Adds one member verifier plus optional tags.
Member: <verifier> [<tags>...]
Member-Delegate
Delegates membership from another config source. Pipe separator
| is required.
Member-Delegate: [<group>]|[<verifier>[/<tai>/<hash>]] [<mods>...]
Defaults:
- omitted group means current group
- omitted verifier means signer of current packet
Pinned form:
<verifier>/<tai>/<hash>pins to exact member packet version
Modifier:
dynamicfollows unpinned delegates
Tag modifiers:
*: inherit all tags+tag: inherit tag if presenttag: grant tag!tag: deny tag
Traversal is depth-first with max depth 8.
Watch/Reload Trigger Map
| Packet coordinate | Effect |
|---|---|
//<group>/admin/ring2//auth/|/seal/<repo-verifier> |
reload Ring2 auth-config cache for
<group> |
//<group>/admin/members//root/|/seal/<verifier> |
reload group membership cache; revalidate active Ring2 WATCH subscribers for that group |
//<group>/admin/ring2//policy/|/seal/<repo-verifier> |
reload ACL snapshot; apply ACL changes to active WATCH streams |
Load and Evaluation Order
- parse the repository request envelope
- read auth config from
//<group>/admin/ring2//auth/|/seal/<repo-verifier> - resolve membership from
//<group>/admin/members//root/|/seal/<verifier> - verify member verifier; produce authenticated principal or enter non-member runtime path
- load policy from
//<group>/admin/ring2//policy/|/seal/<repo-verifier> - evaluate
read/write/listper 050 - workflow packets under
//<group>/admin/request//...are ordinary stored packets subject to policy, not auth-config state
🖧INGEST Ring2
Admission
🖧INGEST uses the submitted Seal’s signer as packet
authority.
Validation:
- Payload must be a complete full top-level Seal.
- The embedded Plex
Groupselects the Ring2 group. - The submitted Seal
Seal-Bymust resolve through currentMember/Member-Delegateexpansion for that group. - The Ring2 auth config must exist, be valid, and not be expired.
- The Ring2 policy must grant
writeon the exact submitted Seal coordinate://<group>/<api>//<key>/|/seal/<seal-by>/<tai>/<seal-hash>.
Ring2 INGEST never uses the non-member runtime path
and never falls back to Ring1 anyone ACL rules. A
non-member signer is rejected even if public anyone
policy would allow writing the target coordinate.
🖧MEMBERS
Returns expanded member list with tags.
Payload is a // URC.
Shorthand:
//<group>expands to//<group>/admin/members//root/|/seal/<repo-verifier>
Response:
- LF-separated lines:
<verifier> [<tags>...] - sorted by verifier
WATCH
WATCH events are filtered by list permission per 050. ACL changes to group auth, member, or
policy packets take effect on active streams immediately. No
reconnect needed.
Errors
Common Ring2 failures:
HELLO_REQUIREDUNAUTHORIZED invalid signatureUNAUTHORIZED not a memberNOT_FOUND ring2 configINVALID configINVALID sessionUNAUTHORIZED ring2