Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions PROVENANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,30 @@ of coverage, and this source-reuse route does not permit GPL/AGPL dependencies
or bundles. The checked-in Classic distribution remains GPL-2.0-or-later; MIT
permission applies only to the exact selected destination material recorded by
the review.

`provenance/identity-reference.synthetic.json` demonstrates the canonical
privacy-preserving identity reference workflow for issue #84. It is
reviewer-signed synthetic evidence only: it grants no permission for real
material and copies neither the coordinator registry nor identity aliases.
`tools/check-foundations.sh` always validates the local record shape. With an
explicit coordinator checkout it also performs bounded offline verification:

```sh
ATRINIK_COORDINATOR=/path/to/atrinik tools/check-foundations.sh
```

Before coordinator PR #381 merges, audit its pushed branch without treating
the result as approval:

```sh
ATRINIK_COORDINATOR=/path/to/atrinik \
ATRINIK_COORDINATOR_TRUSTED_REF=origin/feat/privacy-preserving-provenance-registry \
tools/check-provenance-identity-reference.sh
```

The record's `evidence_reference.url` is the immutable online permalink.
This permanently synthetic demonstration remains a non-authorizing audit of
the exact pushed feature commit. Production evidence must instead pin a
revision already reachable from `origin/main` (or a future implemented and
verified signed release); squash-merging PR #381 does not promote its internal
commits to production authority.
28 changes: 28 additions & 0 deletions provenance/identity-reference.synthetic.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"schema_version": 1,
"synthetic": true,
"source": {
"repository": "atrinik/synthetic-history",
"path": "engine/beta.c",
"revision": "2222222222222222222222222222222222222222"
},
"destination": {
"repository": "atrinik/server",
"path": "internal/kernel/kernel.go"
},
"transformation": "Synthetic port used only to verify the reference contract.",
"scope_binding": "psb-22222222222222222222222222222222",
"scope_approval": {
"key_id": "synthetic-reviewer-2026",
"signature": "-----BEGIN SSH SIGNATURE-----\nU1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgBruVWBv4FEuaHvyX1z13qRO9BU\nTXED0DGAjTaWDx1NAAAAAVYXRyaW5pay1wcm92ZW5hbmNlLXYxAAAAAAAAAAZzaGE1MTIA\nAABTAAAAC3NzaC1lZDI1NTE5AAAAQIIntFyZwxlBb8JrL5UGvsL55gDCSPrsD63OUhQdDz\n1u0Aiv3EtOOR5D79Ort0aOsVmoADkKb3IVmxYRM7vt3wI=\n-----END SSH SIGNATURE-----"
},
"evidence_reference": {
"repository": "atrinik/atrinik",
"revision": "51aa7ac9d5ae9c0ff0b2a24a46b5d3e97739bbe0",
"record_id": "pir-c-22222222222222222222222222222222",
"registry_sha256": "0a04fcadccb37e64f6c1209bc0b7e8d5762639ce4c5521c3bba028d9eba037bd",
"schema_sha256": "9c726627c8679b4b437db2b54b2480fe0c45eef788de7cd76de1dec5c3ce3409",
"reviewers_sha256": "b7a44ad27cec663a9092b924a0f6a9c95bf95a2ce74cf75ba8873e7938782240",
"url": "https://github.com/atrinik/atrinik/blob/51aa7ac9d5ae9c0ff0b2a24a46b5d3e97739bbe0/governance/provenance-identities/registry.json#pir-c-22222222222222222222222222222222"
}
}
1 change: 1 addition & 0 deletions tools/check-foundations.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ required=(CONTRIBUTING.md PROVENANCE.md SECURITY.md THIRD_PARTY_NOTICES.md)
for document in "${required[@]}"; do
test -s "${document}"
done
tools/test-provenance-identity-reference.sh

if grep -RhE '^[[:space:]]*uses:' .github/workflows \
| grep -Ev '@[0-9a-f]{40}([[:space:]]|$)' >/dev/null; then
Expand Down
39 changes: 39 additions & 0 deletions tools/check-provenance-identity-reference.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail

repository=$(git rev-parse --show-toplevel)
record=${1:-"${repository}/provenance/identity-reference.synthetic.json"}

jq -e '
type == "object" and
(keys | sort) == ["destination", "evidence_reference", "schema_version", "scope_approval", "scope_binding", "source", "synthetic", "transformation"] and
.schema_version == 1 and .synthetic == true and
(.source | type == "object" and (keys | sort) == ["path", "repository", "revision"] and
.repository == "atrinik/synthetic-history" and .path == "engine/beta.c" and
(.revision | test("^[0-9a-f]{40}$"))) and
(.destination | type == "object" and (keys | sort) == ["path", "repository"] and
.repository == "atrinik/server" and .path == "internal/kernel/kernel.go") and
(.transformation | type == "string" and length > 0) and
(.scope_approval | type == "object" and (keys | sort) == ["key_id", "signature"] and
.key_id == "synthetic-reviewer-2026" and
(.signature | test("^-----BEGIN SSH SIGNATURE-----\\n[A-Za-z0-9+/=\\n]+\\n-----END SSH SIGNATURE-----$"))) and
(.evidence_reference | type == "object" and
(keys | sort) == ["record_id", "registry_sha256", "repository", "reviewers_sha256", "revision", "schema_sha256", "url"] and
.repository == "atrinik/atrinik" and
.record_id == "pir-c-22222222222222222222222222222222" and
([.registry_sha256, .reviewers_sha256, .schema_sha256] | all(test("^[0-9a-f]{64}$"))) and
(.revision | test("^[0-9a-f]{40}$")) and
(. as $e | $e.url == ("https://github.com/atrinik/atrinik/blob/" + $e.revision +
"/governance/provenance-identities/registry.json#" + $e.record_id))) and
(.scope_binding | test("^psb-[0-9a-f]{32}$")) and
true
' "${record}" >/dev/null

if [[ -n "${ATRINIK_COORDINATOR:-}" ]]; then
trusted_ref=${ATRINIK_COORDINATOR_TRUSTED_REF:-origin/main}
arguments=(provenance validate --reference "${record}")
if [[ "${trusted_ref}" != origin/main ]]; then
arguments+=(--non-authorizing-audit-ref "${trusted_ref}")
fi
"${ATRINIK_COORDINATOR}/atrinik" "${arguments[@]}"
fi
21 changes: 21 additions & 0 deletions tools/test-provenance-identity-reference.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail

repository=$(git rev-parse --show-toplevel)
source_record="${repository}/provenance/identity-reference.synthetic.json"
temporary=$(mktemp /tmp/atrinik-server-provenance-reference.XXXXXX)
trap 'rm -f -- "${temporary}"' EXIT

tools/check-provenance-identity-reference.sh "${source_record}"
for mutation in \
'.source = null' \
'.destination.contact = "forbidden"' \
'.evidence_reference.registry_sha256 = "invalid"' \
'.evidence_reference.url = "https://example.invalid/movable"' \
'.scope_approval.signature = "placeholder"'; do
jq "${mutation}" "${source_record}" >"${temporary}"
if tools/check-provenance-identity-reference.sh "${temporary}"; then
echo "malformed provenance identity reference passed: ${mutation}" >&2
exit 1
fi
done