You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Corrige l'incohérence documentation/code : tous les modules Python
(proxy.py, receipts, tests) utilisent `provider_payment` mais SPEC.md
référençait `payment_evidence`. Mise à jour des 10 occurrences dans
SPEC.md et du note field dans test-vectors.json.
Ajout Sigstore Rekor comme 3e témoin dans :
- Section 7 (table témoins indépendants)
- Section 7.1 "Transparency log (Sigstore Rekor)" (nouveau)
- Champ optionnel `transparency_log` dans la spec des champs
- Note : transparency_log est post-chain-hash (n'affecte pas la formule)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: SPEC.md
+35-11Lines changed: 35 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -101,7 +101,7 @@ A conformant proof is a JSON object. The following fields are **required**:
101
101
}
102
102
```
103
103
104
-
**Note:** proofs without `payment_evidence` may use `spec_version: "1.1"` (backward compatible). Proofs with `payment_evidence.receipt_content_hash` use `spec_version: "2.0"`.
104
+
**Note:** proofs without `provider_payment` may use `spec_version: "1.1"` (backward compatible). Proofs with `provider_payment.receipt_content_hash` use `spec_version: "2.0"`.
105
105
106
106
### Payment variants
107
107
@@ -121,7 +121,7 @@ All variants produce a valid chain hash. The `payment.transaction_id` value is u
121
121
|-------|------|-------------|
122
122
|`spec_version`| string | Proof format version (`"1.1"` or `"2.0"`). Informational for auditors |
123
123
|`upstream_timestamp`| string | Upstream service's HTTP `Date` header (RFC 7231 format). **Included in chain hash** when present |
124
-
|`payment_evidence`| object | External receipt verification (see section 2.1). `receipt_content_hash`**included in chain hash** when present |
124
+
|`provider_payment`| object | External receipt verification (see section 2.1). `receipt_content_hash`**included in chain hash** when present |
125
125
|`arkforge_signature`| string | Ed25519 signature of the chain hash. Format: `ed25519:<base64url_without_padding>`|
126
126
|`arkforge_pubkey`| string | Ed25519 public key used for signing. Format: `ed25519:<base64url_without_padding>`|
127
127
|`verification_url`| string | URL to verify and view the proof (e.g. `https://arkforge.fr/trust/v1/proof/<proof_id>`) |
@@ -134,6 +134,7 @@ All variants produce a valid chain hash. The `payment.transaction_id` value is u
134
134
|`upstream_status_code`| int | HTTP status code returned by the upstream service |
135
135
|`disputed`| bool | Whether this proof has been disputed. Set by the dispute system |
136
136
|`dispute_id`| string | Reference to the dispute record (e.g. `disp_a1b2c3d4`). Set when disputed |
137
+
|`transparency_log`| object | Sigstore Rekor entry. **Post-chain-hash metadata, does not affect chain hash formula.** See section 7.1 |
|`upstream_timestamp`|`upstream_timestamp`| Upstream service's HTTP `Date` header (optional — only included when the field is present and non-null) |
159
-
|`receipt_content_hash`|`payment_evidence.receipt_content_hash`| SHA-256 hex digest of raw receipt bytes (optional — only included when present). Strip the `sha256:` prefix before concatenation |
160
+
|`receipt_content_hash`|`provider_payment.receipt_content_hash`| SHA-256 hex digest of raw receipt bytes (optional — only included when present). Strip the `sha256:` prefix before concatenation |
Each optional component is discriminated by **presence of its field** in the proof JSON:
181
182
-`upstream_timestamp`: if the field is absent or null, do not append. If present and non-null, append after `seller`.
182
-
-`receipt_content_hash`: if `payment_evidence.receipt_content_hash` is absent or null, do not append. If present, strip the `sha256:` prefix and append after `upstream_timestamp` (or after `seller` if `upstream_timestamp` is absent).
183
+
-`receipt_content_hash`: if `provider_payment.receipt_content_hash` is absent or null, do not append. If present, strip the `sha256:` prefix and append after `upstream_timestamp` (or after `seller` if `upstream_timestamp` is absent).
183
184
184
185
Do **not** use `spec_version` for this decision (avoids string comparison pitfalls like `"1.10" < "1.9"`).
185
186
@@ -191,7 +192,7 @@ A proof MAY include external payment evidence — an independently fetched recei
@@ -218,7 +219,7 @@ A proof MAY include external payment evidence — an independently fetched recei
218
219
219
220
### Chain hash impact
220
221
221
-
When `payment_evidence.receipt_content_hash` is present, its value (with the `sha256:` prefix stripped) is appended to the chain hash input. This binds the external receipt to the proof — modifying the receipt content after the fact invalidates the chain hash.
222
+
When `provider_payment.receipt_content_hash` is present, its value (with the `sha256:` prefix stripped) is appended to the chain hash input. This binds the external receipt to the proof — modifying the receipt content after the fact invalidates the chain hash.
222
223
223
224
### What payment evidence proves vs. does not prove
**Not covered** (mutable metadata): `identity_consistent`, `timestamp_authority` status, `transaction_success`, `upstream_status_code`, `disputed`, `dispute_id`. These fields are informational and may change after proof creation.
357
358
@@ -367,13 +368,36 @@ A proof MAY be corroborated by independent witnesses:
|**Ed25519 Signature**| Proof was issued by ArkForge | Verify `arkforge_signature` with `arkforge_pubkey`| All plans |
369
370
|**RFC 3161 Timestamp**| Proof existed at claimed time | Verify `.tsr` file via `openssl ts -verify`| All plans |
371
+
|**Sigstore Rekor**| Chain hash registered in append-only public log | See section 7.1 | All plans |
370
372
|**Stripe**| Payment occurred | Check `payment.transaction_id` on Stripe dashboard or API | Pro plan only |
371
-
|**External Receipt**| Receipt content at time of proof | Fetch `payment_evidence.receipt_url`, hash content, compare to `receipt_content_hash`| When `payment_evidence` is present |
373
+
|**External Receipt**| Receipt content at time of proof | Fetch `provider_payment.receipt_url`, hash content, compare to `receipt_content_hash`| When `provider_payment` is present |
372
374
373
-
Free tier proofs have 2 witnesses (Ed25519, RFC 3161). Pro proofs add Stripe as a 3rd witness. Proofs with external payment evidence add the receipt as an additional witness.
375
+
Free tier proofs have 3 witnesses (Ed25519, RFC 3161, Sigstore Rekor). Pro proofs add Stripe as a 4th witness. Proofs with external payment evidence add the receipt as an additional witness.
374
376
375
377
No witness is required for chain hash verification. Each adds an independent layer of trust.
376
378
379
+
### 7.1 Transparency log (Sigstore Rekor)
380
+
381
+
Rekor is an append-only public transparency log operated by the Linux Foundation under the Sigstore project. When present, `transparency_log` contains:
If Rekor is unavailable at proof creation time, `status` is `"failed"` and the proof remains valid (all other witnesses are unaffected).
396
+
397
+
**Important**: `transparency_log` is post-chain-hash metadata. It is populated after the chain hash is computed and **does not affect the chain hash formula**. Verifiers MUST NOT include `transparency_log` in chain hash recomputation.
398
+
399
+
**Independent verification**: Visit `verify_url` or fetch `log_url` directly to confirm the chain hash was registered in the public log without relying on ArkForge.
400
+
377
401
## 8. Test vectors
378
402
379
403
See [`test-vectors.json`](test-vectors.json) for machine-readable test cases.
"note": "transaction_id = payment.transaction_id from the proof JSON (pi_*, crd_*, or free_tier). buyer_fingerprint = SHA256(api_key). All concatenation uses raw strings, no separator. upstream_timestamp is appended only when present and non-null in the proof JSON. receipt_content_hash is appended only when payment_evidence.receipt_content_hash is present (stripped of sha256: prefix). In test vector inputs, the field is named payment_intent_id for historical reasons.",
6
+
"note": "transaction_id = payment.transaction_id from the proof JSON (pi_*, crd_*, or free_tier). buyer_fingerprint = SHA256(api_key). All concatenation uses raw strings, no separator. upstream_timestamp is appended only when present and non-null in the proof JSON. receipt_content_hash is appended only when provider_payment.receipt_content_hash is present (stripped of sha256: prefix). In test vector inputs, the field is named payment_intent_id for historical reasons.",
0 commit comments