Establish Coulomb scoped recovery API custody and native boundaries
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a17f16-d99c-7ea3-95f0-8212897fba6b
This commit is contained in:
parent
ccc0f8b578
commit
849f3947dc
8 changed files with 784 additions and 13 deletions
45
docs/credential-lane-designs/coulomb-recovery-api.json
Normal file
45
docs/credential-lane-designs/coulomb-recovery-api.json
Normal 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
|
||||
}
|
||||
53
docs/credential-lane-designs/coulomb-recovery-api.md
Normal file
53
docs/credential-lane-designs/coulomb-recovery-api.md
Normal 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.
|
||||
445
docs/evidence/2026-10-29-coulomb-recovery-api-bootstrap.json
Normal file
445
docs/evidence/2026-10-29-coulomb-recovery-api-bootstrap.json
Normal 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
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue