feat: prepare empty Anthropic custody entry for UI handoff
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0726e-5232-73f2-aaca-2c05ceb62efb
This commit is contained in:
parent
cb6396caab
commit
a16c33942a
2 changed files with 126 additions and 22 deletions
|
|
@ -10,11 +10,16 @@ in_flight:
|
||||||
missing_fields:
|
missing_fields:
|
||||||
- openbao.policy_file
|
- openbao.policy_file
|
||||||
- openbao.auth
|
- openbao.auth
|
||||||
blocking_reason: Anthropic organization and workspace budget await user input; the sandbox owner machine identity and protected delivery path have not been verified. No live grant or key exists from this request.
|
blocking_reason: Provider organization, key name and expiration supplied by user.
|
||||||
|
Empty-only KV seed authorized for operator UI handoff; live custody and the sandbox
|
||||||
|
owner machine identity/delivery remain unverified. Workspace scope and budget
|
||||||
|
are not confirmed.
|
||||||
owner: railiance-platform
|
owner: railiance-platform
|
||||||
requester:
|
requester:
|
||||||
agent: codex
|
agent: codex
|
||||||
reason: User selected a dedicated Anthropic workload API key for GLAS-WP-0012 and SAND-WP-0015. Establish custody and owner delivery before the real local Claude proof.
|
reason: User selected a dedicated Anthropic workload API key for GLAS-WP-0012 and
|
||||||
|
SAND-WP-0015. Establish custody and owner delivery before the real local Claude
|
||||||
|
proof.
|
||||||
review:
|
review:
|
||||||
required: true
|
required: true
|
||||||
required_approvers:
|
required_approvers:
|
||||||
|
|
@ -24,13 +29,21 @@ review:
|
||||||
- at: '2026-09-05'
|
- at: '2026-09-05'
|
||||||
reviewer: user via chat
|
reviewer: user via chat
|
||||||
decision: authentication_model_selected
|
decision: authentication_model_selected
|
||||||
comment: User requested establishment of an Anthropic workload API key. This records the chosen authentication model; final machine bindings are not yet known.
|
comment: User requested establishment of an Anthropic workload API key. This records
|
||||||
|
the chosen authentication model; final machine bindings are not yet known.
|
||||||
|
- at: '2026-09-05'
|
||||||
|
reviewer: user via chat
|
||||||
|
decision: empty_seed_authorized
|
||||||
|
comment: User authorized preparing the existing proposed location with an empty
|
||||||
|
version; user will create a version containing the secret through the OpenBao
|
||||||
|
UI. No runtime grant authorized by this seed.
|
||||||
target:
|
target:
|
||||||
domain: infotech
|
domain: infotech
|
||||||
tenant: glas-harness
|
tenant: glas-harness
|
||||||
workload: sand-boxer-claude-agent-dev
|
workload: sand-boxer-claude-agent-dev
|
||||||
environment: production
|
environment: production
|
||||||
purpose: Dedicated Claude Code inference for the Glas local agent-dev profile, delivered by the sandbox owner.
|
purpose: Dedicated Claude Code inference for the Glas local agent-dev profile, delivered
|
||||||
|
by the sandbox owner.
|
||||||
openbao:
|
openbao:
|
||||||
mount: platform
|
mount: platform
|
||||||
kv_path: platform/workloads/glas-harness/claude-agent-dev
|
kv_path: platform/workloads/glas-harness/claude-agent-dev
|
||||||
|
|
@ -46,34 +59,71 @@ access_frontdoor:
|
||||||
resolvable: false
|
resolvable: false
|
||||||
delivery:
|
delivery:
|
||||||
surface: owner-exec
|
surface: owner-exec
|
||||||
target: Sand-boxer delivers ANTHROPIC_API_KEY only to the selected Claude workload; neither the Glas caller nor the runtime receives an OpenBao token.
|
target: Sand-boxer delivers ANTHROPIC_API_KEY only to the selected Claude workload;
|
||||||
|
neither the Glas caller nor the runtime receives an OpenBao token.
|
||||||
risk:
|
risk:
|
||||||
classification: high
|
classification: high
|
||||||
notes:
|
notes:
|
||||||
- Proposed KV coordinates and catalog selector are reserved design names, not surveyed live objects.
|
- Proposed KV coordinates and catalog selector are reserved design names, not surveyed
|
||||||
- Provider credential can incur API charges; use a dedicated workspace and user-selected budget.
|
live objects.
|
||||||
- Use a workspace-scoped service account key; organization administration is outside the workload grant.
|
- Provider credential can incur API charges; use a dedicated workspace and user-selected
|
||||||
- OpenBao token expiration does not expire the provider key. Provider revocation is required for compromise.
|
budget.
|
||||||
- Owner environment injection can expose the key to descendants within that workload; it is not per-process secrecy against workload code.
|
- Use a workspace-scoped service account key; organization administration is outside
|
||||||
|
the workload grant.
|
||||||
|
- OpenBao token expiration does not expire the provider key. Provider revocation
|
||||||
|
is required for compromise.
|
||||||
|
- Owner environment injection can expose the key to descendants within that workload;
|
||||||
|
it is not per-process secrecy against workload code.
|
||||||
verification:
|
verification:
|
||||||
positive:
|
positive:
|
||||||
- Confirm provider organization, workspace, service account, key identifier and expiration using metadata only.
|
- Confirm provider organization, workspace, service account, key identifier and
|
||||||
- Exact authenticated sandbox owner can read only the intended data entry and deliver the field without logging it.
|
expiration using metadata only.
|
||||||
- Bounded real Claude proof succeeds through enforced provider egress and removes private state on teardown.
|
- Exact authenticated sandbox owner can read only the intended data entry and deliver
|
||||||
|
the field without logging it.
|
||||||
|
- Bounded real Claude proof succeeds through enforced provider egress and removes
|
||||||
|
private state on teardown.
|
||||||
negative:
|
negative:
|
||||||
- Wrong owner identity, sibling KV path, metadata read, parent listing and workload writes are denied.
|
- Wrong owner identity, sibling KV path, metadata read, parent listing and workload
|
||||||
|
writes are denied.
|
||||||
- Generic coding-agent identity cannot retrieve the credential directly.
|
- Generic coding-agent identity cannot retrieve the credential directly.
|
||||||
- No credential or OpenBao token appears in execution replies, artifacts, source tree or State Hub.
|
- No credential or OpenBao token appears in execution replies, artifacts, source
|
||||||
|
tree or State Hub.
|
||||||
- A revoked predecessor provider key fails authentication after controlled rotation.
|
- A revoked predecessor provider key fails authentication after controlled rotation.
|
||||||
activation_conditions:
|
activation_conditions:
|
||||||
- User confirms Anthropic organization and workspace budget; provider service account and key are created through attended Console custody.
|
- User confirms Anthropic organization and workspace budget; provider service account
|
||||||
- Confirm actual sandbox host service identity and auth binding; review exact read policy and separate protected custody writer before apply.
|
and key are created through attended Console custody.
|
||||||
- Seed KV with compare-and-set zero through attended custody; never enter values in chat or command arguments.
|
- Confirm actual sandbox host service identity and auth binding; review exact read
|
||||||
- Positive and negative access, owner delivery and provider authentication evidence pass before route activation.
|
policy and separate protected custody writer before apply.
|
||||||
|
- Seed KV with compare-and-set zero through attended custody; never enter values
|
||||||
|
in chat or command arguments.
|
||||||
|
- Positive and negative access, owner delivery and provider authentication evidence
|
||||||
|
pass before route activation.
|
||||||
|
evidence:
|
||||||
|
- at: '2026-09-05'
|
||||||
|
actor: codex
|
||||||
|
kind: empty_seed
|
||||||
|
result: passed
|
||||||
|
details:
|
||||||
|
- Empty ANTHROPIC_API_KEY version 1 created with CAS zero; user will create version
|
||||||
|
2 in UI.
|
||||||
|
- Request id 50cafc25-8d24-c1d6-5be8-1ade049e088b.
|
||||||
|
- Provider metadata recorded; metadata-only recovery completed after empty response
|
||||||
|
parsing fix; contained sessions revoked.
|
||||||
|
- No secret data read or real key handled; runtime lane remains inactive.
|
||||||
lifecycle:
|
lifecycle:
|
||||||
deactivate: Disable the owner route and provider key; revoke outstanding OpenBao reader tokens. Preserve KV history under platform retention rules.
|
deactivate: Disable the owner route and provider key; revoke outstanding OpenBao
|
||||||
rotate: Create a replacement provider key, write with expected-version CAS, stop old runs, verify new delivery and inference, then revoke the predecessor at Anthropic and prove its denial.
|
reader tokens. Preserve KV history under platform retention rules.
|
||||||
compromised: Disable the provider key immediately, stop affected runs and owner route, revoke Bao leases, replace forward through protected custody and record non-secret incident evidence.
|
rotate: Create a replacement provider key, write with expected-version CAS, stop
|
||||||
|
old runs, verify new delivery and inference, then revoke the predecessor at Anthropic
|
||||||
|
and prove its denial.
|
||||||
|
compromised: Disable the provider key immediately, stop affected runs and owner
|
||||||
|
route, revoke Bao leases, replace forward through protected custody and record
|
||||||
|
non-secret incident evidence.
|
||||||
state_hub:
|
state_hub:
|
||||||
workplan_id: GLAS-WP-0012
|
workplan_id: GLAS-WP-0012
|
||||||
task_id: GLAS-WP-0012-T02
|
task_id: GLAS-WP-0012-T02
|
||||||
|
provider_metadata:
|
||||||
|
organization_id: e1a8f305-9e64-4639-a7fd-af48e34f37c7
|
||||||
|
key_name: claude_key_bernd.worsch
|
||||||
|
expires_at: '2027-01-31T21:00:00Z'
|
||||||
|
source: user supplied; provider identity and workspace scope not independently verified
|
||||||
|
|
|
||||||
54
scripts/prepare-glas-anthropic.py
Normal file
54
scripts/prepare-glas-anthropic.py
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""User-authorized empty KV seed for CCR-2026-0016; silent OIDC child."""
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
DATA_PATH = 'platform/data/workloads/glas-harness/claude-agent-dev'
|
||||||
|
META_PATH = 'platform/metadata/workloads/glas-harness/claude-agent-dev'
|
||||||
|
RECEIPT = Path('/tmp/glas-anthropic-empty-receipt.json')
|
||||||
|
|
||||||
|
def bao(*args, payload=None):
|
||||||
|
r = subprocess.run(['bao', *args], input=None if payload is None else json.dumps(payload),
|
||||||
|
text=True, capture_output=True, timeout=30)
|
||||||
|
if r.returncode:
|
||||||
|
raise RuntimeError('bao_operation_failed')
|
||||||
|
return json.loads(r.stdout) if r.stdout.strip() else {}
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if sys.argv[1:] == ['--complete-metadata']:
|
||||||
|
receipt = json.loads(RECEIPT.read_text())
|
||||||
|
if receipt.get('path') != DATA_PATH or receipt.get('version') != 1:
|
||||||
|
raise RuntimeError('invalid_receipt')
|
||||||
|
observed = bao('read', '-format=json', META_PATH)['data']
|
||||||
|
if observed.get('current_version', 0) < 1:
|
||||||
|
raise RuntimeError('missing_seed')
|
||||||
|
elif not sys.argv[1:]:
|
||||||
|
# CAS zero makes concurrent creation and existing versions refuse; no data GET.
|
||||||
|
result = bao('write', '-format=json', DATA_PATH, '-',
|
||||||
|
payload={'options': {'cas': 0}, 'data': {'ANTHROPIC_API_KEY': ''}})
|
||||||
|
version = result['data']['version']
|
||||||
|
receipt = {'ccr': 'CCR-2026-0016', 'path': DATA_PATH, 'version': version,
|
||||||
|
'empty_seed_created': True, 'metadata_written': False,
|
||||||
|
'request_id': result.get('request_id')}
|
||||||
|
with RECEIPT.open('x') as f:
|
||||||
|
json.dump(receipt, f)
|
||||||
|
else:
|
||||||
|
raise RuntimeError('invalid_arguments')
|
||||||
|
# Only non-secret custom metadata. No secret expiry is enforced by KV metadata.
|
||||||
|
bao('write', '-format=json', META_PATH, '-', payload={'custom_metadata': {
|
||||||
|
'ccr': 'CCR-2026-0016', 'custody_owner': 'railiance-platform',
|
||||||
|
'provider': 'anthropic', 'organization_id': 'e1a8f305-9e64-4639-a7fd-af48e34f37c7',
|
||||||
|
'provider_key_name': 'claude_key_bernd.worsch',
|
||||||
|
'provider_expires_at': '2027-01-31T21:00:00Z',
|
||||||
|
'seed_version': '1', 'seed_contains_secret': 'false',
|
||||||
|
'handoff': 'operator creates next version in UI; runtime lane remains inactive'}})
|
||||||
|
receipt['metadata_written'] = True
|
||||||
|
RECEIPT.write_text(json.dumps(receipt))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except Exception:
|
||||||
|
sys.exit(1) # contained executor must never return provider/client output
|
||||||
Loading…
Add table
Add a link
Reference in a new issue