@@ -101,13 +101,44 @@ and only when, they appear in all capitals, as shown here.
101101 and, across delegation chains, matching pins are REQUIRED where they affect
102102 evaluation.
103103
104+ ### 2.3 Ecosystem Terminology
105+
106+ PSP‑1 references several terms defined in related Polykey specifications. These terms
107+ describe the various placements and roles of enforcement agents and adapters:
108+
109+ - ** CEP(R) (Resource‑side CEP):** A CEP embedded in or colocated with the
110+ Resource itself; it verifies Presentations natively on behalf of the resource.
111+ - ** CEP(P) (Principal‑side CEP):** A CEP operated within the Principal's trust
112+ domain; it is used when the Resource is non‑PK‑native or to bridge to external
113+ systems.
114+ - ** CEP(S) (Subject‑side CEP):** A CEP operated within the Subject's domain;
115+ often used for wallet‑style session management or when the Subject can derive
116+ credentials via federated identity.
117+ - ** Bridge Adapter (BA):** A specialized CEP that bridges to a non‑PK‑native
118+ Source of Authority (SoA) using a long‑lived upstream lease. A BA mediates
119+ between Polykey Grants/Presentations and legacy authorization systems.
120+ Subtypes include:
121+ - ** PS‑BA (Principal‑side BA):** The typical pattern where the Principal's
122+ agent holds the upstream lease and performs legacy enforcement on behalf of
123+ the resource.
124+ - ** SS‑BA (Subject‑side BA):** A less common pattern where the Subject holds
125+ a lease and bridges a resource it controls to Polykey.
126+ - ** Exposure Mode:** The method by which a Bridge Adapter handles secrets when
127+ interacting with legacy systems. Modes include ** mediate** (the adapter
128+ performs the action and does not expose raw secrets), ** derive** (the
129+ adapter mints a short‑lived, scoped token), and ** reveal** (the adapter
130+ returns the raw secret under strict, TAP‑governed constraints). Exposure mode
131+ policies and receipt placement are defined in the CEP/BA specification and
132+ TAP/RAM.
133+
104134## Overview and Goals
105135
106136PSP-1 provides the core capability model for Polykey: the program model and
107137verification semantics that allow independent parties to mint, hold, present,
108138and verify capabilities across boundaries.
139+ ### 3.1 Goals and Design Principles
109140
110- What PSP- 1 defines:
141+ PSP‑ 1 defines the following core constructs and invariants for Polykey :
111142
112143- Capability Program (CPL/0): a monotone program with finite Declarations
113144 (PairSet/ActionSet/ResourceSet), normalized into a Program Canonical Form
@@ -475,7 +506,7 @@ specific, immutable entry or snapshot in one of these registries.
475506Channel ` lattice ` and ` channel_lattice_id ` :
476507
477508- A channel lattice defines a partial order over channel profiles (e.g.,
478- mtls:v1 >= tls_exporter :v1 >= dpop:v1 >= bearer:v1). It is the rulebook used
509+ mtls:v1 >= tls-exporter :v1 >= dpop:v1 >= bearer:v1). It is the rulebook used
479510 by the builtin channel_geq(channel, floor).
480511- channel_lattice_id is the content-addressed ID of the specific lattice used to
481512 interpret ">=". It is required whenever a Program uses channel_geq.
@@ -703,9 +734,13 @@ A conforming Grant MUST satisfy all of the following.
703734 form defined in PSP-4).
704735 - builtins_id: Content-addressed identifier of the Builtins registry
705736 snapshot used by the Program.
706- - channel_lattice_id: REQUIRED if and only if the Program contains
707- channel_geq literals; OPTIONAL otherwise. When present, it pins the
708- channel lattice used to interpret >=.
737+ - channel_lattice_id: REQUIRED if and only if the Program contains
738+ ` channel_geq ` literals; OPTIONAL otherwise. When present, it pins the
739+ channel lattice used to interpret >=.
740+ - schemes_snapshot_id: REQUIRED. A content‑addressed manifest that pins
741+ comparator semantics for all scheme names referenced by this Grant’s
742+ declarations. CEPs MUST load this manifest to resolve scheme
743+ comparators. Unknown or missing snapshots MUST cause deny.
7097442 . Envelope and framing
710745 - The envelope (issuer, subject, issuance/validity timestamps, prev linkage,
711746 signatures, canonical bytes for the entire claim) is defined in PSP-3.
@@ -820,17 +855,18 @@ defined in PSP-3.
820855
821856``` json
822857{
823- "program_id " : " mh:..." , // multihash(program_bytes ) per PSP-3
824- "program_bytes " : " ..." , // ENCODE(PCF(Program)) per PSP-3
858+ "programId " : " mh:..." , // multihash(programBytes ) per PSP-3
859+ "programBytes " : " ..." , // ENCODE(PCF(Program)) per PSP-3
825860 "declarations" : {
826861 "pairs:cid:Qm..." : " ..." , // canonical bytes of PairSet
827862 "actions:cid:Qn..." : " ..." , // canonical bytes of ActionSet (if used)
828863 "resources:cid:Qr..." : " ..." // canonical bytes of ResourceSet (if used)
829864 },
830865 "pins" : {
831- "lang_version" : " cpl/0@1" ,
832- "builtins_id" : " cid:builtins@YYYYMMDD" ,
833- "channel_lattice_id" : " cid:lattice@1" // REQUIRED iff Program uses channel_geq
866+ "langVersion" : " cpl/0@1" ,
867+ "builtinsId" : " cid:builtins@YYYYMMDD" ,
868+ "channelLatticeId" : " cid:lattice@1" , // REQUIRED iff Program uses channel_geq
869+ "schemesSnapshotId" : " cid:schemes@YYYYMMDD" // REQUIRED: pins scheme comparator semantics
834870 }
835871}
836872```
@@ -962,7 +998,7 @@ payload). PSP-1 does not define a Presentation 'payload' vs 'envelope' split.
962998 "iat": 1768099200,
963999 "exp": 1768099320,
9641000 "channelBinding": {
965- "profile": "tls_exporter :v1",
1001+ "profile": "tls-exporter :v1",
9661002 "value": "base64url(exporter)"
9671003 },
9681004 "ctx": { "ns": "ci", "pod": "runner-xyz" },
@@ -1124,7 +1160,7 @@ A CEP MUST deny if any of the following holds:
11241160- TTL:
11251161 - Parent ttl_ok(iat, now, 300) -> Child ttl_ok(iat, now, 120) (valid).
11261162- Channel floor:
1127- - Parent channel_geq(channel, "tls_exporter :v1") -> Child channel_geq(channel,
1163+ - Parent channel_geq(channel, "tls-exporter :v1") -> Child channel_geq(channel,
11281164 "mtls:v1") (valid; equal or stronger only).
11291165- Context:
11301166 - Parent ctx_eq("ns","prod") -> Child ctx_eq("ns","prod") $\land$
@@ -1235,7 +1271,7 @@ Preconditions (TAP-governed, outside evaluation)
12351271 - Validate required conceptual fields: presenter, grant_ref, iat, exp, jti,
12361272 channelBinding, ctx.
12371273 - Capture a single logical now at the start of enforcement. Enforce
1238- Presentation lifetime window using this now: now >= iat AND now < exp
1274+ the Presentation lifetime window using this now: ` iat <= now < exp`
12391275 (subject to TAP clock discipline); else deny.
124012762 . Verify PoP and channel binding
12411277 - Verify the presenter's proof-of-possession signature over the Presentation
@@ -1527,6 +1563,7 @@ Notes:
15271563- All CIDs, program_id, and bytes shown are illustrative.
15281564- On-wire field names and encodings are defined in PSP-3.
15291565- Actions are plain strings; resource semantics come from scheme comparators.
1566+ - Field names in the JSON projections below use ** camelCase** for readability. These labels are ** illustrative only** ; the normative field names and encodings are defined in PSP‑3. Implementers MUST NOT rely on these example names.
15301567
15311568### Example 1: DevOps - Read a secret from Vault
15321569
@@ -1569,15 +1606,16 @@ Grant (payload only, non-normative)
15691606
15701607```
15711608{
1572- "program_id ": "mh:QmProgDev1",
1573- "program_bytes ": "<PCF-bytes>",
1609+ "programId ": "mh:QmProgDev1",
1610+ "programBytes ": "<PCF-bytes>",
15741611 "declarations": {
15751612 "pairs:bafyPairsDev1": "<PairSet-bytes>"
15761613 },
15771614 "pins": {
1578- "lang_version": "cpl/0@1",
1579- "builtins_id": "cid:builtins@2025-09-01",
1580- "channel_lattice_id": "cid:channel-lattice@v1"
1615+ "langVersion": "cpl/0@1",
1616+ "builtinsId": "cid:builtins@2025-09-01",
1617+ "channelLatticeId": "cid:channel-lattice@v1",
1618+ "schemesSnapshotId": "cid:schemes@2025-09-01"
15811619 }
15821620}
15831621```
@@ -1587,12 +1625,12 @@ Presentation (conceptual fields; non-normative)
15871625```
15881626{
15891627 "presenter": "did:pk:ci-runner-01",
1590- "grant_ref ": "cid://G_leaf_devops",
1628+ "grantRef ": "cid://G_leaf_devops",
15911629 "iat": 1768100050,
15921630 "exp": 1768100170,
15931631 "jti": "uuid-1234",
15941632 "channelBinding": { "profile": "mtls:v1", "value": "base64url(exporter)" },
1595- "ctx": { "ns": "prod", "app": "web", "pod": "runner-xyz" },
1633+ "ctx": { "ns": "prod", "app": "web", "pod": "runner-xyz" }
15961634}
15971635```
15981636
@@ -1668,15 +1706,16 @@ Grant (payload only, non-normative)
16681706
16691707```
16701708{
1671- "program_id ": "mh:QmProgDbMint1",
1672- "program_bytes ": "<PCF-bytes>"
1709+ "programId ": "mh:QmProgDbMint1",
1710+ "programBytes ": "<PCF-bytes>",
16731711 "declarations": {
16741712 "pairs:bafyPairsDbMint1": "<PairSet-bytes>"
16751713 },
16761714 "pins": {
1677- "lang_version": "cpl/0@1",
1678- "builtins_id": "cid:builtins@2025-09-01",
1679- "channel_lattice_id": "cid:channel-lattice@v1"
1715+ "langVersion": "cpl/0@1",
1716+ "builtinsId": "cid:builtins@2025-09-01",
1717+ "channelLatticeId": "cid:channel-lattice@v1",
1718+ "schemesSnapshotId": "cid:schemes@2025-09-01"
16801719 }
16811720}
16821721```
@@ -1686,12 +1725,12 @@ Presentation (conceptual fields; non-normative)
16861725```
16871726{
16881727 "presenter": "did:pk:ci-runner-prod-01",
1689- "grant_ref ": "cid://G_leaf_dbmint",
1728+ "grantRef ": "cid://G_leaf_dbmint",
16901729 "iat": 1768100050,
16911730 "exp": 1768100170,
16921731 "jti": "uuid-9a7b",
16931732 "channelBinding": { "profile": "mtls:v1", "value": "base64url(exporter)" },
1694- "ctx": { "ns": "prod", "app": "web", "purpose": "sha256:artifact-H", "pod": "runner-xyz" },
1733+ "ctx": { "ns": "prod", "app": "web", "purpose": "sha256:artifact-H", "pod": "runner-xyz" }
16951734}
16961735```
16971736
@@ -1748,7 +1787,7 @@ Program (CPL/0, AST)
17481787 (any
17491788 (and
17501789 (in_pairset action resource Pairs#bafyPairsDoor1)
1751- (channel_geq channel "tls_exporter :v1")
1790+ (channel_geq channel "tls-exporter :v1")
17521791 (within_time now 1768102000 1768102600)
17531792 (ttl_ok iat now 60)
17541793 (ctx_eq "visitor_id" "door-visit-123")
@@ -1772,15 +1811,16 @@ Grant (payload only, non-normative)
17721811
17731812```
17741813{
1775- "program_id ": "mh:QmProgDoor1",
1776- "program_bytes ": "<PCF-bytes>",
1814+ "programId ": "mh:QmProgDoor1",
1815+ "programBytes ": "<PCF-bytes>",
17771816 "declarations": {
17781817 "pairs:bafyPairsDoor1": "<PairSet-bytes>"
17791818 },
17801819 "pins": {
1781- "lang_version": "cpl/0@1",
1782- "builtins_id": "cid:builtins@2025-09-01",
1783- "channel_lattice_id": "cid:channel-lattice@v1"
1820+ "langVersion": "cpl/0@1",
1821+ "builtinsId": "cid:builtins@2025-09-01",
1822+ "channelLatticeId": "cid:channel-lattice@v1",
1823+ "schemesSnapshotId": "cid:schemes@2025-09-01"
17841824 }
17851825}
17861826```
@@ -1790,18 +1830,18 @@ Presentation (conceptual fields; non-normative)
17901830```
17911831{
17921832 "presenter": "did:pk:mobile-app-42",
1793- "grant_ref ": "cid://G_leaf_door",
1833+ "grantRef ": "cid://G_leaf_door",
17941834 "iat": 1768102050,
17951835 "exp": 1768102100,
17961836 "jti": "uuid-5678",
1797- "channelBinding": { "profile": "tls_exporter :v1", "value": "base64url(exporter)" },
1798- "ctx": { "visitor_id ": "door-visit-123", "device": "ios" }
1837+ "channelBinding": { "profile": "tls-exporter :v1", "value": "base64url(exporter)" },
1838+ "ctx": { "visitorId ": "door-visit-123", "device": "ios" }
17991839}
18001840```
18011841
18021842CEP evaluation outline (resource-side CEP, OT-aware)
18031843
1804- 1 . PoP and channel: valid; tls_exporter bound to session.
1844+ 1 . PoP and channel: valid; tls-exporter bound to session.
180518452 . Leaf Grant found locally; signatures ok; Grant envelope (if present) $\land$
18061846 Presentation window ok.
180718473 . Revocation: not revoked.
@@ -1810,7 +1850,7 @@ CEP evaluation outline (resource-side CEP, OT-aware)
181018506 . Program evaluation:
18111851 - in_pairset("access:open","door:building-12:lock-3",Pairs#bafyPairsDoor1):
18121852 true
1813- - channel_geq("tls_exporter :v1","tls_exporter :v1"): true (equal under
1853+ - channel_geq("tls-exporter :v1","tls-exporter :v1"): true (equal under
18141854 lattice)
18151855 - within_time(now,1768102000,1768102600): true (10-minute window)
18161856 - ttl_ok(iat,now,60): true
@@ -1927,7 +1967,8 @@ definitions.
19271967 - Types: all Int.
19281968 - Tightening: child interval $\subseteq$ parent interval (i.e.,
19291969 ` nbf_child >= nbf_parent ` and ` exp_child <= exp_parent ` ).
1930- - Fail-closed: ill-typed or now outside [ nbf, exp] => false; unknown => deny.
1970+ - Fail-closed: ill-typed or ` now ` outside the half‑open interval ` [nbf, exp) `
1971+ results in ` false ` ; unknown => deny.
19311972
19321973- ttl_ok(iat:Int, now:Int, ttl_max:Int)
19331974
0 commit comments