Skip to content

Commit b5aefe3

Browse files
committed
wip: psp-1 review
1 parent 3b0fc51 commit b5aefe3

File tree

1 file changed

+154
-27
lines changed

1 file changed

+154
-27
lines changed

docs/reference/specifications/psp-1.mdx

Lines changed: 154 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,17 @@ receipt formats and proof traces are defined in PSP-2; enforcement
3737
placement/modes are defined in the CEP/BA specification; acceptance and
3838
governance live in TAP/RAM and related profiles.
3939

40-
## Terminology
40+
## Terminology and Requirements Language
41+
42+
### Requirements Language
4143

4244
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
4345
"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
4446
document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when,
4547
and only when, they appear in all capitals, as shown here.
4648

49+
### Core Terminology
50+
4751
- **Principal (P):** Originator of authority; issues a Grant to a Subject.
4852
- **Subject (S):** Holder of a Grant that exercises the capability by creating a
4953
Presentation.
@@ -221,21 +225,38 @@ Deterministic Evaluation and PSP-4).
221225
- The `now: Int` fact is CEP-provided and subject to TAP time-discipline; PSP-1
222226
is agnostic to the time source.
223227

224-
#### Relationship with Biscuit Datalog (Informative)
225-
226-
- CPL/0 intentionally defines the checks-only, monotone fragment (no user atoms,
227-
variables, rules, recursion, or negation). This fragment maps 1:1 to Biscuit
228-
checks:
229-
- Program (all of Checks) $\cong$ multiple Biscuit check blocks (all must
230-
pass).
231-
- Check (any of Queries) $\cong$ a Biscuit check with multiple queries (OR).
232-
- Query (and of Literals) $\cong$ a Biscuit query's conjunction.
233-
- Rationale: simple PCF and stable program_id; syntactic attenuation;
234-
deterministic, ms-class verification and compact proof traces.
235-
- Interop: Biscuit tokens in the checks-only fragment can be normalized into
236-
CPL/0. If rules are required in a domain, precompute finite sets and ship a
237-
CPL/0 guard, or use a TAP-gated policy that supplies a compiled guard or an
238-
approved CEP runtime.
228+
#### Relationship with Biscuit Datalog
229+
230+
- Fragment alignment. CPL/0 defines the checks-only, monotone fragment (no user
231+
atoms, variables, rules, recursion, or negation). This corresponds to the
232+
Biscuit checks fragment without rules, where each check is an OR of queries,
233+
and each query is an AND of ground predicates.
234+
- Structural mapping (CPL/0 -> Biscuit):
235+
- Program (ALL of Checks) ? a set of Biscuit check blocks, all of which MUST
236+
pass.
237+
- Check (ANY of Queries) ? a Biscuit check containing multiple queries (OR).
238+
- Query (AND of Literals) ? a Biscuit query whose predicates match CPL/0
239+
literals 1:1.
240+
- Literal (Builtin(op, args...)) ? a ground predicate recognized by the verifier
241+
as the corresponding builtin; arguments are ground terms
242+
(Str/Int/Bool/Bytes).
243+
- Conversion constraints (Biscuit -> CPL/0 normalizer):
244+
1. No rules or user facts are consumed during conversion; only checks are
245+
considered. Any presence of rules, variables, non-ground terms, or
246+
unsupported predicates MUST cause conversion to fail (out of scope for
247+
CPL/0 interop).
248+
2. All predicate identifiers MUST be recognized builtin op_ids in the pinned
249+
builtins_id; argument arity/types MUST match; strings are NFC; Bytes are
250+
exact octets.
251+
3. The resulting CPL/0 Program is constructed as `all(check_i)`; each Biscuit
252+
check yields one CPL/0 Check; each Biscuit query yields one CPL/0 Query;
253+
each recognized predicate yields one CPL/0 Literal.
254+
- Equivalence goal (informative): For tokens inside this fragment and under
255+
identical pinned semantics (builtins/channel lattice/scheme comparators),
256+
verification outcomes SHOULD coincide between Biscuit's check evaluation and
257+
CPL/0 Program evaluation over the same environment facts. Outside this
258+
fragment, issuers SHOULD precompute finite sets and ship a CPL/0 guard, or use
259+
a TAP-gated policy that provides an approved CEP runtime.
239260

240261
Because CPL/0 is checks-only over ground terms with pure, bounded builtins, CEPs
241262
evaluate Programs deterministically and emit minimal proof traces (which check,
@@ -250,7 +271,7 @@ TAP-gated and provide either a compiled CPL/0 guard or an approved CEP runtime.
250271
At verification, the CEP supplies an environment of facts. Builtins may
251272
reference these facts by name.
252273

253-
- Required environment facts (normative)
274+
- Required environment facts
254275
- action: Str - action being attempted (e.g., "secret:read").
255276
- resource: Str - target resource identifier (scheme-normalized).
256277
- now: Int - NumericDate (Unix seconds) at enforcement.
@@ -267,7 +288,7 @@ reference these facts by name.
267288
jurisdiction tags, or digest references) and define how they are obtained
268289
and verified. PSP-1 does not enumerate these; Programs assert them via
269290
equality (e.g., ctx_eq).
270-
- Missing facts and normalization
291+
- Missing facts
271292
- If a builtin present in the Program requires an environment fact that is
272293
missing, evaluation MUST fail closed.
273294
- The CEP MUST normalize `resource` using the same comparator semantics used
@@ -414,7 +435,7 @@ action in A over any resource in R"). Use PairSet when the matrix is irregular.
414435
- CEPs MUST verify subset relations hop-by-hop along the delegation chain using
415436
the same normalization and comparators; failures or unknowns MUST cause deny.
416437

417-
#### Profiles
438+
#### Specification Profiles
418439

419440
This specification standardizes exactly three Declaration kinds: PairSet,
420441
ActionSet, ResourceSet. Specification Profiles MAY further constrain their usage
@@ -1171,7 +1192,7 @@ revocation state) MUST be locally available at enforcement or the CEP MUST deny.
11711192

11721193
Inputs (conceptual)
11731194

1174-
- Presentation P: presenter, grant_ref, iat, exp, jti, channel_binding, ctx, and
1195+
- Presentation P: presenter, grant_ref, iat, exp, jti, channelBinding, ctx, and
11751196
optionally grant_refs (ordered digest hints).
11761197
- Local stores/cache: Grants by digest (leaf and, if applicable, parents),
11771198
revocation state, TAP configuration (anchors, depth caps, resolver policy,
@@ -1185,18 +1206,41 @@ Preconditions (TAP-governed, outside evaluation)
11851206
enforcement. At enforcement time, all required inputs MUST be local; otherwise
11861207
deny.
11871208

1209+
### Time Model & Boundaries
1210+
1211+
- Single time capture: The CEP MUST capture a single logical `now : Int` (Unix
1212+
seconds) at the **start** of enforcement. All time comparisons in this
1213+
algorithm and in builtins evaluation use this same `now`.
1214+
- Half-open windows: Unless a builtin's pinned definition states otherwise, all
1215+
time windows are half-open intervals `[start, end)`, i.e., inclusive of
1216+
`start`, exclusive of `end`.
1217+
- Presentation validity window: `[iat, exp)` - accept iff `iat <= now < exp`.
1218+
- Grant envelope windows (e.g., `not_before`, `not_after` per PSP-3) are also
1219+
treated as half-open and MUST be intersected with the Presentation window.
1220+
- `within_time(now, nbf, exp)` succeeds iff `nbf <= now < exp` under the
1221+
pinned builtins set.
1222+
- `ttl_ok(iat, now, ttl_max)` succeeds iff `now < iat + ttl_max`.
1223+
- Precedence / intersection: When multiple constraints apply (Presentation
1224+
window, Grant envelope, and time-based builtins such as `within_time` and
1225+
`ttl_ok`), the effective acceptance condition is the intersection of all
1226+
applicable constraints at the captured `now`. If any one fails, enforcement
1227+
MUST deny.
1228+
- Time discipline: Clock source and skew tolerance are governed by TAP policy;
1229+
all time comparisons MUST follow TAP's time discipline. If time discipline
1230+
cannot be satisfied (e.g., clock indeterminate), enforcement MUST deny.
1231+
11881232
### Algorithm
11891233

11901234
1. Parse Presentation
11911235
- Validate required conceptual fields: presenter, grant_ref, iat, exp, jti,
1192-
channel_binding, ctx.
1236+
channelBinding, ctx.
11931237
- Capture a single logical now at the start of enforcement. Enforce
11941238
Presentation lifetime window using this now: now >= iat AND now < exp
11951239
(subject to TAP clock discipline); else deny.
11961240
2. Verify PoP and channel binding
11971241
- Verify the presenter's proof-of-possession signature over the Presentation
11981242
payload; else deny.
1199-
- Verify channel_binding matches the live session per the declared profile
1243+
- Verify channelBinding matches the live session per the declared profile
12001244
(e.g., TLS exporter, DPoP); else deny.
12011245
3. Resolve and verify the leaf Grant (local)
12021246
- Locate the leaf Grant by grant_ref in local storage; if unavailable, deny.
@@ -1438,7 +1482,7 @@ across delegation, and (d) TAP-governed acceptance and deployment hygiene.
14381482

14391483
- Timing behavior
14401484
- CEPs SHOULD aim for consistent-time checks and minimize data-dependent
1441-
timing variations in hot paths (especially channel_binding and signature
1485+
timing variations in hot paths (especially channelBinding and signature
14421486
checks).
14431487
- Error reporting
14441488
- Use standardized reason codes (e.g., pcf_mismatch, pin_mismatch, revoked,
@@ -1554,7 +1598,7 @@ Presentation (conceptual fields; non-normative)
15541598

15551599
CEP evaluation outline
15561600

1557-
1. PoP and channel: presenter's signature valid; channel_binding matches mTLS
1601+
1. PoP and channel: presenter's signature valid; channelBinding matches mTLS
15581602
session.
15591603
2. Leaf Grant located locally by grant_ref; signatures valid; Grant envelope
15601604
window intersects with Presentation window.
@@ -1646,14 +1690,14 @@ Presentation (conceptual fields; non-normative)
16461690
"iat": 1768100050,
16471691
"exp": 1768100170,
16481692
"jti": "uuid-9a7b",
1649-
"channel_binding": { "profile": "mtls:v1", "value": "base64url(exporter)" },
1693+
"channelBinding": { "profile": "mtls:v1", "value": "base64url(exporter)" },
16501694
"ctx": { "ns": "prod", "app": "web", "purpose": "sha256:artifact-H", "pod": "runner-xyz" },
16511695
}
16521696
```
16531697

16541698
CEP evaluation outline
16551699

1656-
1. Verify PoP + channel_binding (mTLS exporter).
1700+
1. Verify PoP + channelBinding (mTLS exporter).
16571701
2. Load leaf Grant locally by grant_ref; verify signatures + envelope; enforce
16581702
envelope $\land$ presentation time intersection; check revocation (local).
16591703
3. If delegated: verify custody, prev linkage; pins compatibility; scheme
@@ -1750,7 +1794,7 @@ Presentation (conceptual fields; non-normative)
17501794
"iat": 1768102050,
17511795
"exp": 1768102100,
17521796
"jti": "uuid-5678",
1753-
"channel_binding": { "profile": "tls_exporter:v1", "value": "base64url(exporter)" },
1797+
"channelBinding": { "profile": "tls_exporter:v1", "value": "base64url(exporter)" },
17541798
"ctx": { "visitor_id": "door-visit-123", "device": "ios" }
17551799
}
17561800
```
@@ -2026,3 +2070,86 @@ deny/diagnostic codes to aid auditors:
20262070

20272071
Receipts SHOULD include enough context (program_id, declaration CIDs, pins,
20282072
minimal evaluation trace, and revocation snapshot) for replay.
2073+
2074+
### Appendix E - Conformance Test Vectors
2075+
2076+
The following vectors exercise PCF stability, syntactic attenuation, time
2077+
boundaries, and resource normalization. Each vector specifies inputs and the
2078+
expected decision. Implementations SHOULD include these (or stricter) cases in
2079+
their conformance suites.
2080+
2081+
#### Example 1 PCF Identity Stability - literal reordering
2082+
2083+
Setup: Two Programs differ only by literal order within the same Query.
2084+
2085+
Expect: `program_id` is identical after PCF; evaluation results coincide.
2086+
2087+
Inputs (sketch):
2088+
2089+
```
2090+
P1: (all (any (and (ctx_eq "ns" "prod") (ttl_ok iat now 120))))
2091+
P2: (all (any (and (ttl_ok iat now 120) (ctx_eq "ns" "prod"))))
2092+
```
2093+
2094+
Expected: `multihash(ENCODE(PCF(P1))) == multihash(ENCODE(PCF(P2)))`; both allow
2095+
when ctx.ns="prod" and now < iat+120.
2096+
2097+
#### Example 2 Syntactic Attenuation - valid child (tightened)
2098+
2099+
Setup: Parent Check with Query Q; Child retains the Check, drops no Queries, and
2100+
**adds** a Literal; Declarations child $\subseteq$ parent.
2101+
2102+
Expect: Chain accepted; evaluation allows when both parent and added child
2103+
literals hold.
2104+
2105+
Inputs (sketch):
2106+
2107+
```
2108+
Parent: (all (any (and (in_pairset action resource Pairs#P) (ttl_ok iat now 120))))
2109+
Child: (all (any (and (in_pairset action resource Pairs#C) (ttl_ok iat now 60) (ctx_eq "ns" "prod"))))
2110+
Pairs#C $\subseteq$ Pairs#P
2111+
```
2112+
2113+
Expected: Chain acceptance; allow only if `now < iat+60` and `ctx.ns="prod"`.
2114+
2115+
#### Example 3 Syntactic Attenuation - invalid child (removed Check)
2116+
2117+
Setup: Parent has two Checks (AND); Child omits one parent Check.
2118+
2119+
Expect: attenuation_failure at chain verification.
2120+
2121+
Inputs (sketch):
2122+
2123+
```
2124+
Parent: (all ( (any (and (ctx_eq "ns" "prod"))) (any (and (channel_geq channel "mtls:v1"))) ))
2125+
Child: (all ( (any (and (ctx_eq "ns" "prod"))) )) ; second Check missing
2126+
```
2127+
2128+
Expected: Deny with reason `attenuation_failure`.
2129+
2130+
#### Example 4 Time Boundaries - half-open edges
2131+
2132+
Setup: `iat=100`, `exp=200`. `ttl_ok(iat, now, 100)`.
2133+
2134+
Expect: Allow for `now $\in$ {100,...,199}`, deny for `now=200` (Presentation window)
2135+
and `now=200` (TTL boundary).
2136+
2137+
Inputs: `now=199` => allow; `now=200` => deny.
2138+
2139+
Expected: At `now=200`, both `now < exp` and `now < iat+ttl_max` **fail**.
2140+
2141+
#### Example 5 Resource Normalization - percent-encoding equivalence
2142+
2143+
Setup: Declaration contains `api:https://api.example.com/a%2Fb`; env.resource is
2144+
`api:https://api.example.com/a/b`. Comparator defines canonical normalization
2145+
collapsing these to the same normalized form.
2146+
2147+
Expect: After normalization, `in_pairset(action, resource, Pairs#X)` is true.
2148+
2149+
Expected: Allow (assuming other literals hold); deny if normalization fails.
2150+
2151+
#### Example 6 Comparator Snapshot Pinning - mismatch across chain
2152+
2153+
Setup: Parent pins `schemes_snapshot_id = S1`; Child pins `S2 != S1`.
2154+
2155+
Expect: Deny at chain verification with `pin_mismatch`.

0 commit comments

Comments
 (0)