Establish Coulomb scoped recovery API custody and native boundaries
Some checks are pending
CCR intake gate / gate (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
CI Smoke / host-smoke (push) Waiting to run

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a17f16-d99c-7ea3-95f0-8212897fba6b
This commit is contained in:
codex 2026-10-29 22:13:06 +01:00
parent ccc0f8b578
commit 849f3947dc
8 changed files with 784 additions and 13 deletions

View file

@ -0,0 +1,45 @@
{
"schema": "platform.coulomb-recovery-api.v1",
"project_id": "06d107bc-9d84-4672-b2a0-95701cc0c07f",
"region": "nl-ams",
"custody_owner": "railiance-platform/platform-root",
"public_recipient": "age1qm30jk8q0cezey652dk2dhcr3d9vs528v6lg8mavl6d4q3e3vgnqmrmyy3",
"materials": {
"age": {
"id": "634e4b9f-0b61-4329-a83c-1ed0e76c4636",
"revision": 1,
"name": "coulomb-social-age-recovery"
},
"reader-pair": {
"id": "241742f7-d3b5-4163-8d87-3a3d9585778d",
"revision": 1,
"name": "coulomb-social-recovery-reader-api"
},
"custodian-pair": {
"id": "cf44e9bd-9edc-450b-9f10-564ee3008305",
"revision": 1,
"name": "coulomb-social-recovery-custodian-api"
}
},
"applications": {
"custodian": "f80037a2-87c9-44d2-9163-3e6907af3ced",
"reader": "7a4055fc-a3f5-40bf-8013-cd0eec9028de"
},
"routine_key_expirations": {
"reader": "2027-10-28T19:24:59.647270Z",
"custodian": "2027-10-28T19:25:00.458446Z"
},
"buckets": {
"kits": {
"name": "railiance-coulomb-social-recovery",
"prefix": "kits/",
"automatic_expiry_enabled": false
},
"archives": {
"name": "railiance-coulomb-social-archives",
"prefix": "archives/",
"automatic_expiry_enabled": false
}
},
"native_application_recovery_verified": false
}

View file

@ -0,0 +1,53 @@
# Coulomb recovery API custody
Owner: railiance-platform / platform-root. Admission decisions
27bbc1ac-e275-42be-ba34-6cf16eae4e78 and 6139e02b-3fb7-4eff-be8a-efe127c45ce5.
Non-secret coordinates: coulomb-recovery-api.json. Native evidence:
../evidence/2026-10-29-coulomb-recovery-api-bootstrap.json.
Routine access uses separate reader/custodian API pairs under an owner-private
directory outside Git, normally ~/.config/railiance-platform/coulomb-social-recovery/.
The worker holds only its original publisher pair and the dedicated public age
recipient. Never deliver the custodian pair, reader pair or private age identity
to that worker. No sibling credentials or private keys are reused.
Check independent retrieval without writing a private identity:
```sh
python3 scripts/application_recovery_access.py --execute --material age
```
For an isolated attended restore, add --output with a fresh absolute filename
under an existing owner-private directory outside Git. The helper validates exact
project/name/protection/revision/nonexpiry and public recipient before writing
mode0600. Materials reader-pair and custodian-pair use the same front door;
omit --output to verify retrieval without creating another secret copy.
No value goes to stdout, Git, State Hub, shell arguments or environment.
The reader performs only prefix/version reads and listing in the isolated project.
The custodian can also publish new kit versions and read the dedicated escrow;
neither can delete retained versions or administer buckets/IAM. Scaleway's current
2023-04-17 bucket policies intersect IAM with an explicit allowlist. Deletion is
absent while publisher multipart abort is included; native checks prove both.
Negative PUT probes use separate transports because a denied upload can leave
the provider connection unusable for its next request.
Both buckets are private and versioned; no automatic expiry has been enabled.
The protected bucket never participates in rolling expiry. Rolling retention,
capacity, first coherent app capture, independent exact-version decryption and
isolated application recovery, monitoring and timers remain WP-0053/CSOC-WP-0012
acceptance work. Synthetic fixtures are boundary evidence, not app backups.
The routine pairs and age identity each have a separate protected, enabled,
nonexpiring provider secret version. They survive node/workstation loss. If all
local routine credentials are lost, platform-root uses its existing independent
account/MFA recovery to retrieve only the custodian escrow coordinate in the
public contract, then returns to the API front door. Emergency owner recovery is
separate from routine drill access; preserve the platform-root recovery mechanism.
Routine API keys expire on 2027-10-28; exact timestamps are in the JSON contract.
Platform-root owns renewal and independently read-back escrow before those
deadlines, using a bounded attended construction window. No standing organization
administration key or publisher IAM administration is admitted. The construction
key was revoked, its temporary pair removed and the personal browser context
closed without saving state. Routine drills do not rerun identity bootstrap.

View file

@ -0,0 +1,445 @@
{
"programmatic_direction_reference": "6139e02b-3fb7-4eff-be8a-efe127c45ce5",
"applications": {
"bootstrap": "2a355842-e03b-42a3-8af7-6cd8f8b98bcd",
"custodian": "f80037a2-87c9-44d2-9163-3e6907af3ced",
"reader": "7a4055fc-a3f5-40bf-8013-cd0eec9028de"
},
"automatic_expiry_enabled": false,
"bootstrap_key_revoked_verified": true,
"buckets": {
"railiance-coulomb-social-archives": {
"created": true,
"lifecycle_rules": [],
"policy": {
"Id": "coulomb-independent-recovery",
"Statement": [
{
"Action": "s3:*",
"Effect": "Allow",
"Principal": {
"SCW": "user_id:3d029efb-4f70-4f82-a3bb-cefbe255232b"
},
"Resource": [
"railiance-coulomb-social-archives",
"railiance-coulomb-social-archives/*"
],
"Sid": "PlatformOwner"
},
{
"Action": "s3:*",
"Effect": "Allow",
"Principal": {
"SCW": "application_id:2a355842-e03b-42a3-8af7-6cd8f8b98bcd"
},
"Resource": [
"railiance-coulomb-social-archives",
"railiance-coulomb-social-archives/*"
],
"Sid": "TemporaryConstruction"
},
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Effect": "Allow",
"Principal": {
"SCW": "application_id:7a4055fc-a3f5-40bf-8013-cd0eec9028de"
},
"Resource": "railiance-coulomb-social-archives/archives/*",
"Sid": "readerObjects"
},
{
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"archives/",
"archives/*"
]
}
},
"Effect": "Allow",
"Principal": {
"SCW": "application_id:7a4055fc-a3f5-40bf-8013-cd0eec9028de"
},
"Resource": "railiance-coulomb-social-archives",
"Sid": "readerList"
},
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:PutObject"
],
"Effect": "Allow",
"Principal": {
"SCW": "application_id:f80037a2-87c9-44d2-9163-3e6907af3ced"
},
"Resource": "railiance-coulomb-social-archives/archives/*",
"Sid": "custodianObjects"
},
{
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"archives/",
"archives/*"
]
}
},
"Effect": "Allow",
"Principal": {
"SCW": "application_id:f80037a2-87c9-44d2-9163-3e6907af3ced"
},
"Resource": "railiance-coulomb-social-archives",
"Sid": "custodianList"
},
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts"
],
"Effect": "Allow",
"Principal": {
"SCW": "application_id:681d00bf-b965-4323-b657-97bfde423511"
},
"Resource": "railiance-coulomb-social-archives/archives/*",
"Sid": "publisherObjects"
},
{
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"archives/",
"archives/*"
]
}
},
"Effect": "Allow",
"Principal": {
"SCW": "application_id:681d00bf-b965-4323-b657-97bfde423511"
},
"Resource": "railiance-coulomb-social-archives",
"Sid": "publisherList"
},
{
"Action": [
"s3:GetBucketLocation",
"s3:GetBucketVersioning",
"s3:GetLifecycleConfiguration"
],
"Effect": "Allow",
"Principal": {
"SCW": [
"application_id:7a4055fc-a3f5-40bf-8013-cd0eec9028de",
"application_id:f80037a2-87c9-44d2-9163-3e6907af3ced",
"application_id:681d00bf-b965-4323-b657-97bfde423511"
]
},
"Resource": "railiance-coulomb-social-archives",
"Sid": "ArchiveMetadata"
}
],
"Version": "2023-04-17"
},
"public_acl_absent": true,
"versioning": "Enabled"
},
"railiance-coulomb-social-recovery": {
"created": true,
"lifecycle_rules": [],
"policy": {
"Id": "coulomb-independent-recovery",
"Statement": [
{
"Action": "s3:*",
"Effect": "Allow",
"Principal": {
"SCW": "user_id:3d029efb-4f70-4f82-a3bb-cefbe255232b"
},
"Resource": [
"railiance-coulomb-social-recovery",
"railiance-coulomb-social-recovery/*"
],
"Sid": "PlatformOwner"
},
{
"Action": "s3:*",
"Effect": "Allow",
"Principal": {
"SCW": "application_id:2a355842-e03b-42a3-8af7-6cd8f8b98bcd"
},
"Resource": [
"railiance-coulomb-social-recovery",
"railiance-coulomb-social-recovery/*"
],
"Sid": "TemporaryConstruction"
},
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Effect": "Allow",
"Principal": {
"SCW": "application_id:7a4055fc-a3f5-40bf-8013-cd0eec9028de"
},
"Resource": "railiance-coulomb-social-recovery/kits/*",
"Sid": "readerObjects"
},
{
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"kits/",
"kits/*"
]
}
},
"Effect": "Allow",
"Principal": {
"SCW": "application_id:7a4055fc-a3f5-40bf-8013-cd0eec9028de"
},
"Resource": "railiance-coulomb-social-recovery",
"Sid": "readerList"
},
{
"Action": [
"s3:GetBucketLocation",
"s3:GetBucketVersioning",
"s3:GetLifecycleConfiguration"
],
"Effect": "Allow",
"Principal": {
"SCW": "application_id:7a4055fc-a3f5-40bf-8013-cd0eec9028de"
},
"Resource": "railiance-coulomb-social-recovery",
"Sid": "readerMetadata"
},
{
"Action": [
"s3:GetObject",
"s3:GetObjectVersion",
"s3:PutObject"
],
"Effect": "Allow",
"Principal": {
"SCW": "application_id:f80037a2-87c9-44d2-9163-3e6907af3ced"
},
"Resource": "railiance-coulomb-social-recovery/kits/*",
"Sid": "custodianObjects"
},
{
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"kits/",
"kits/*"
]
}
},
"Effect": "Allow",
"Principal": {
"SCW": "application_id:f80037a2-87c9-44d2-9163-3e6907af3ced"
},
"Resource": "railiance-coulomb-social-recovery",
"Sid": "custodianList"
},
{
"Action": [
"s3:GetBucketLocation",
"s3:GetBucketVersioning",
"s3:GetLifecycleConfiguration"
],
"Effect": "Allow",
"Principal": {
"SCW": "application_id:f80037a2-87c9-44d2-9163-3e6907af3ced"
},
"Resource": "railiance-coulomb-social-recovery",
"Sid": "custodianMetadata"
}
],
"Version": "2023-04-17"
},
"public_acl_absent": true,
"versioning": "Enabled"
}
},
"completed_at": "2026-10-29T20:59:12.852425+00:00",
"decision": "27bbc1ac-e275-42be-ba34-6cf16eae4e78",
"native_application_recovery_verified": false,
"native_checks": {
"archives_custodian_delete": {
"denied": true,
"http_status": 403
},
"archives_custodian_outside_prefix": {
"denied": true,
"http_status": 403
},
"archives_custodian_policy_write": {
"denied": true,
"http_status": 403
},
"archives_publisher_delete": {
"denied": true,
"http_status": 403
},
"archives_publisher_outside_prefix": {
"denied": true,
"http_status": 403
},
"archives_publisher_policy_write": {
"denied": true,
"http_status": 403
},
"archives_reader_delete": {
"denied": true,
"http_status": 403
},
"archives_reader_outside_prefix": {
"denied": true,
"http_status": 403
},
"archives_reader_policy_write": {
"denied": true,
"http_status": 403
},
"archives_reader_put": {
"denied": true,
"http_status": 403
},
"archives_reader_version_get_hash": {
"verified": true,
"version_id": "1793307392673579"
},
"custodian_iam_admin": {
"denied": true,
"http_status": 403
},
"kits_custodian_delete": {
"denied": true,
"http_status": 403
},
"kits_custodian_outside_prefix": {
"denied": true,
"http_status": 403
},
"kits_custodian_policy_write": {
"denied": true,
"http_status": 403
},
"kits_publisher_delete": {
"denied": true,
"http_status": 403
},
"kits_publisher_outside_prefix": {
"denied": true,
"http_status": 403
},
"kits_publisher_policy_write": {
"denied": true,
"http_status": 403
},
"kits_reader_delete": {
"denied": true,
"http_status": 403
},
"kits_reader_outside_prefix": {
"denied": true,
"http_status": 403
},
"kits_reader_policy_write": {
"denied": true,
"http_status": 403
},
"kits_reader_put": {
"denied": true,
"http_status": 403
},
"kits_reader_version_get_hash": {
"verified": true,
"version_id": "1793307384956710"
},
"publisher_create_readback": {
"verified": true
},
"publisher_escrow": {
"denied": true,
"http_status": 403
},
"publisher_iam_admin": {
"denied": true,
"http_status": 403
},
"publisher_own_multipart_abort": {
"verified": true
},
"publisher_protected_kit_get": {
"denied": true,
"http_status": 403
},
"reader_escrow": {
"denied": true,
"http_status": 403
},
"reader_iam_admin": {
"denied": true,
"http_status": 403
}
},
"organization_wide_grants": false,
"personal_browser_context_closed": true,
"personal_state_saved": false,
"private_values_printed": false,
"project_id": "06d107bc-9d84-4672-b2a0-95701cc0c07f",
"project_only_policies_verified": 4,
"protected_secret_references": {
"coulomb-social-age-recovery": {
"id": "634e4b9f-0b61-4329-a83c-1ed0e76c4636",
"revision": 1
},
"coulomb-social-recovery-access-canary": {
"id": "db825503-cf12-4bfd-8cc5-f16d09edd8b5",
"revision": 1
},
"coulomb-social-recovery-custodian-api": {
"id": "cf44e9bd-9edc-450b-9f10-564ee3008305",
"revision": 1
},
"coulomb-social-recovery-reader-api": {
"id": "241742f7-d3b5-4163-8d87-3a3d9585778d",
"revision": 1
}
},
"public_recipient": "age1qm30jk8q0cezey652dk2dhcr3d9vs528v6lg8mavl6d4q3e3vgnqmrmyy3",
"publisher_pair_replaced": false,
"routine_age_and_both_pairs_retrieved_without_personal_session": true,
"schema": "platform.coulomb-recovery-bootstrap.v1",
"temporary_pair_removed": true,
"timers_activated": false
}