Outcome
Implement the Codefly host lifecycle for external provider bindings:
- environment binding and CLI UX;
- principal/PDP/approval composition;
- hardened provider process launch;
- host-driven per-action execution;
- durable state, locking, ownership, checkpoints, and signed receipts;
- configuration projection and local durable secret sink;
- public callback resolution;
- static and remote doctor behavior;
- explicit local/production-observe/production-mutation admission gates.
This is the first real CLI wiring of Codefly's existing permission primitives.
Do not describe it as already implemented reuse.
Dependencies and parallelism
Contract dependency:
Security-boundary dependency/interfaces:
F3 may develop in parallel with F2 after F1 freezes their shared interfaces.
F3 acceptance uses the real F2 broker, not a permissive stub.
F4 conformance waits for F1-F3.
Repository ownership
Primary: codefly-dev/cli
Linked Core changes stay as a checklist in this issue:
- provider agent session/launcher;
core/agents/manager/loader.go;
core/runners/sandbox/;
- Core policy composition helpers where provider-neutral;
- configuration writer/local sink;
- environment provider-binding resources;
- endpoint/public-origin resolution;
- execution-receipt glue.
Likely CLI areas:
- new
cmd/provider
- new
pkg/provider coordinator/state/approval/receipt packages
- command JSON and exit-code contracts
- agent/session lifecycle
No Stripe/Sentry/Resend branch is allowed in Core or CLI.
Product workflow
The founder path:
codefly provider setup billing --env local-dogfood
must:
- load workspace/environment/binding;
- resolve/install the digest-bound provider;
- safely collect public inputs and secret references;
- acquire/validate the initiating principal;
- launch the provider through the hardened profile;
- validate offline;
- observe remotely through F2;
- resolve endpoints/origins;
- calculate a deterministic plan;
- authorize every exact action and request approval where required;
- execute one action at a time;
- persist checkpoint/state/capture before the next effect;
- execute
PROJECT_OUTPUT through the host writer;
- emit signed receipts;
- run bounded provider doctor checks;
- print the product run command;
- rerun with no diff.
Deliverables
1. Environment provider bindings
Add an environment-scoped provider-bindings map:
- stable binding name;
- exact provider agent identity/version;
- input configuration;
- output configuration and contract;
- management mode (
observe, managed, disabled);
- deletion policy (
retain default, delete-owned explicit);
- non-secret provider spec;
- endpoint references;
- API-origin selection;
- sink/state policy.
Requirements:
- secrets forbidden in
spec;
- literal generated ports/URLs rejected where semantic endpoint references are
required;
- old CLI silent-ignore risk is diagnosed with minimum-version/doctor output;
- bindings cannot target undeclared output contracts;
- observe mode cannot express remote mutations;
- disabled mode does not start agents;
- import/adoption is exact-ID and explicit.
2. Eight-command CLI
Implement:
codefly provider list [BINDING] [--schema] [--env ENV]
codefly provider setup BINDING --env ENV [--dry-run]
codefly provider plan BINDING --env ENV
[--validate-only | --refresh-only] [--out PLAN]
codefly provider apply --plan PLAN
codefly provider doctor [BINDING] --env ENV
codefly provider import BINDING TYPE REMOTE_ID --env ENV
codefly provider disconnect BINDING --env ENV
codefly provider destroy BINDING --env ENV
Stable exits:
- 0 success/no diff/apply complete;
- 1 invalid/config/compatibility/unclassified failure;
- 2 valid diff present;
- 3 policy denied;
- 4 approval required;
- 5 partial;
- 6 uncertain;
- 7 stale plan/state/endpoint.
All commands support deterministic JSON where meaningful. No JSON/human output
may contain secret values or raw provider bodies.
--yes suppresses a prompt only after policy permits; it cannot mint
authority. There is no generic --force bypass.
Local-state plan files are non-portable and bind exact workspace/state
generation. Cross-runner plan/apply requires H1 shared state and lock.
3. Principal acquisition and permission composition
Wire existing Core primitives into CLI provider operations:
- acquire and validate a human/service/agent
policy.Principal;
- preserve organization/delegation chain;
- compose SaaS PDP with manifest ceiling and operator policy;
- use
GatewayEvaluator;
- use Ed25519 scoped authorization for providers;
- bind audience, catalog/request digest, action/resource, TTL, use count, and
caveats;
- wire owner-only permission callback UDS;
- wire escalation/approval and grantor attribution;
- require
WithProductionAdmission;
- fail closed on backend/callback/signature/expiry errors.
The provider cannot choose the principal. The callback server uses the
spawn-time principal.
Authorize at:
- operation dispatch;
- every exact plan action;
- every broker request (F2 derives action/resource);
- every state/output/sink commit.
Recheck revocation/policy before each remote effect and commit. A revoked grant
stops later actions and records partial/denied evidence.
Production admission rejects:
- missing/expired principal;
WithoutPrincipal;
- AllowAll/shadow-only/off PDP;
- missing callback;
- HMAC provider authorization;
- broad
* or provider:<name>/* mutation grants;
- unverified provider artifacts;
- unapproved live account/origin;
- break-glass hidden behind
--force.
Break-glass is a distinct governed, receipted operation.
4. Hardened provider launch
Current generic agent spawn inherits os.Environ() and current macOS sandbox
does not enforce the proposed hostile-binary read boundary. Providers require
a new mandatory capacity profile.
Host requirements:
- authenticated owner-only UDS only; no TCP fallback;
- child environment starts empty;
- allow only protocol, locale, bounded temp, and public verification values;
- never inherit
OP_*, proxy variables, *_KEY, *_SECRET, arbitrary
CODEFLY_*, or HMAC scoped-auth signing material;
- provider receives Ed25519 public verification key only;
- non-overridable external-network deny;
- no workspace/configuration/secret-store/provider-state reads;
- no workspace writes;
- only per-spawn UDS/temp paths;
- no shell/vendor CLI/secret resolver/arbitrary subprocess tools;
- separate provider processes cannot access one another's sockets/state;
- cleanup on cancellation/crash.
Linux:
- clear environment;
- unshare network/PID/IPC/UTS as required;
- mount only provider binary/runtime libs and explicit paths;
- do not expose other same-UID process environments.
macOS:
- replace
(allow default) read behavior with a qualified provider read
policy;
- deny workspace,
~/.codefly, secret/configuration locations, and unrelated
user files;
- prove the policy with hostile e2e tests.
Windows is unsupported until it has equivalent enforcement.
If a platform cannot pass F4 hostile conformance, provider execution is
disabled there.
5. Host-driven per-action lifecycle
For each ordered action:
- hold/revalidate binding lock and compare-and-swap state/output generation;
- re-resolve endpoint/origin and reject change;
- recheck observation freshness/material preconditions;
- authorize exact action/resource;
- persist pre-send checkpoint with request/idempotency/prospective ID;
- call provider
ApplyAction;
- service F2 callbacks only in bound action context;
- acknowledge durable transport/capture checkpoint before another effect;
- persist safe partial state;
- execute host-owned output/state/sink actions;
- emit terminal receipt.
The host coordinator is the sole retry owner.
A same-attempt retry requires the exact request/idempotency identity, qualified
vendor support/window, durable checkpoint, fresh authorization, and budget.
Non-idempotent SENT_OUTCOME_UNKNOWN is UNCERTAIN, never blindly retried.
6. Workspace state and ownership
Implement one 0600 transactional store under a 0700 provider directory per
canonical workspace, with:
- environment/binding buckets;
- workspace-wide
(provider,type,remote-id) -> owner index;
- inter-process locks;
- state schema/version;
- operation/attempt/action/checkpoint journal;
- material observation/plan/output generations;
- ownership and vendor metadata stamp;
- opaque secret references/fingerprints only;
- receipt references;
- partial/uncertain recovery;
- stepwise upgrade and backup.
Requirements:
- canonicalize/evaluate symlinks;
- diagnose workspace relocation rather than silently creating new state;
- exact cross-binding ownership uniqueness;
- compare-and-swap inside the lock at apply admission;
- old agent/new state fails closed;
- state corruption has explicit recovery;
- state never contains raw secrets or bodies.
Remote resources default retained. URL/name/domain/email similarity never
adopts. Import requires exact ID and plan. Destroy deletes only exact
owned/adopted resources under delete-owned.
7. Projection writer and local sink
Implement host-only PROJECT_OUTPUT:
- validate generic contract/schema/version;
- enforce classification/purpose/browser/consumer/provenance;
- scan public values for secret shapes;
- reject path traversal/symlink targets;
- verify secret outputs are ignored or reference-only;
- owner-only temp staging;
0600, fsync, atomic rename;
- compare-and-swap approved current digest;
- refuse unowned differing files;
- ownership metadata stored in provider state, not beside files;
- validate through normal Codefly loader;
- restore re-derivable public output on validation failure;
- never roll back a successful one-time capture.
Local sink:
- deterministic address;
- prepare;
- durable-at-Put;
- lookup;
- abort only unused prepared target;
- opaque reference return;
- no raw secret in state/receipt/provider.
Host-to-host projection of an existing runtime/build credential must not route
bytes through the provider.
Whole-configuration injection requires build-only credentials in a separate
configuration from runtime/browser values.
8. Endpoint and public-origin resolver
Create:
(environment, service, endpoint) -> admitted public HTTPS origin
Requirements:
- semantic endpoint reference in binding/plan;
- dynamic local origin from Codefly runtime;
- public origin from deployment/ingress state;
- relative owned callback path validation;
- no copied/generated port persistence;
- apply re-resolves under lock;
- changed origin invalidates plan before request;
- public mode blocks without stable HTTPS ingress;
- local-forwarded returns exact current callback but does not own a vendor CLI
process.
9. Receipts and audit evidence
Wire signed receipts for provider operations:
- ADMITTED;
- STARTED;
- SUCCEEDED / FAILED / COMPENSATED / UNCERTAIN.
Correlate:
- principal/org/delegation/grantor;
- provider/version/digest;
- workspace/env/binding;
- action/redacted exact resource;
- plan/approval/scoped-auth/operation/attempt/checkpoint IDs;
- allow/deny/approval/fail-closed path;
- safe request/vendor IDs;
- state/output generation.
Never include tokens, credentials, secrets, DSNs, raw bodies, emails, or
arbitrary vendor errors.
Support a local-authority path for founder dogfood without pretending a remote
SaaS Work Context exists, while retaining signed attributable evidence.
10. Doctor split
codefly doctor workspace stays bounded/local/no-agent and checks only:
- binding schema;
- installed compatible provider;
- declared inputs/resolver/sink;
- endpoint/ingress declaration;
- local state/schema/lock;
- output contract/consumer presence.
codefly provider doctor is explicit remote read-only work:
- auth/purpose/scope where observable;
- account/mode/origin;
- complete observation;
- resource health/drift;
- rate limits;
- uncertain recovery;
- provider-specific remediation.
Use external_provider.* diagnostic codes to avoid existing secret-provider
provider_* collision.
11. Readiness gates
Gate A — local dogfood:
- hardened launch passes both supported platforms;
- human principal/PDP matrix;
- local state/sink;
- broker and receipts;
- sandbox/test account policy;
- no-diff second run.
Gate B — production observe:
- verified artifact digest;
- validated principal, no fallback/allow-all/shadow;
- Ed25519 authorization;
- live fail-closed PDP/revocation;
- broker can express reads only;
- account/mode/origin displayed/policy-checked;
- receipt retention;
- existing secret refs only; no mutation/capture.
Gate C — production mutation:
- disabled in F3;
- H1 remote shared state/lock, managed sink, digest locks, DR, rotation, and
multi-user requirements.
Required tests
Permission matrix
- manifest allow + role deny;
- role allow + manifest omit;
- broad grant rejected;
- wrong principal/org/delegation depth;
- wrong environment/account/origin/audience/catalog/request/resource;
- stale plan/state/output;
- create grant cannot update/delete;
- public output grant cannot persist secret;
- management handle cannot become runtime;
- setup/build token not runtime/browser;
- missing/expired principal;
- PDP unavailable;
- callback unavailable;
- revocation between actions;
- approval exactness and expiry;
--yes cannot bypass escalation;
- break-glass distinct;
- denied operation changes nothing.
Hostile spawn/platform
Seed parent environment with poison OP_*, proxy, key, secret, Codefly, and
HMAC values; provider sees none.
On Linux and macOS hostile provider attempts:
- direct external/loopback dial outside broker;
- workspace/secret/config/state reads;
- workspace writes;
- another provider's socket/state;
/proc/process environment where applicable;
op, shell, curl, vendor CLI subprocess;
- proxy bypass;
- TCP fallback.
All fail and produce safe evidence.
State/lifecycle
- concurrent apply;
- stale CAS;
- workspace move/symlink;
- duplicate remote ownership;
- old agent/new state;
- crash before send;
- crash after send/before response;
- response before checkpoint;
- capture success then projection failure;
- state commit then output failure;
- output success then receipt failure;
- remote drift/deletion;
- agent upgrade between plan/apply;
- idempotent retry versus non-idempotent uncertain.
Writer/sink
- traversal/symlink/Git-ignore/mode;
- unowned conflict;
- public secret-shape scan;
- purpose/browser/consumer mismatch;
- atomic multi-file failure;
- CAS conflict;
- durable capture preserved on projection failure;
- lookup after lost local response;
- raw secret absent from every surface.
Endpoint/CLI
- dynamic non-default local ports;
- public ingress missing/changed after approval;
- deterministic JSON/exits;
- local plan non-portability;
- remote Doctor never mutates;
- workspace Doctor starts no agent.
Acceptance criteria
- One setup path performs Validate -> Observe -> Plan -> approval ->
per-action Apply -> Project -> receipts -> Doctor.
- Every action and output commit is attributable to a validated principal and
admitted through existing Codefly policy primitives.
- Provider process receives a scrubbed environment, mandatory UDS, no direct
egress, and no workspace/secret access on Linux and macOS.
- A denied operation changes no broker fixture, state, output, sink, or
receipt terminal facts.
- Concurrent/stale applies fail before an effect.
- Crash/uncertain timelines leave enough durable evidence for safe recovery.
- Public and secret outputs are atomically projected through normal Codefly
configuration injection without provider file access.
- No generated port is persisted.
- Stable JSON and exit codes distinguish diff, denial, approval, partial,
uncertain, and stale.
- Gate A and B can be proven independently; Gate C remains disabled.
- No provider-specific conditional appears in Core/CLI.
Explicit non-goals
- HTTP broker implementation (F2).
- Provider protocol/schema design (F1).
- Provider conformance harness (F4).
- Stripe/Sentry/Resend semantics.
- Vendor CLI/tunnel supervision.
- Remote shared state.
- Production writable secret sink.
- Production mutation.
Review findings discharged
This issue owns coordinator/permission/isolation/state/projection/CLI portions
of ADV-005, ADV-007/008, ADV-010, ADV-012 through ADV-014, ADV-018,
ADV-025 through ADV-031, ADV-038, ADV-040 through ADV-043, ADV-047, and the
associated state, writer, receipt, doctor, platform, and operability findings.
Outcome
Implement the Codefly host lifecycle for external provider bindings:
This is the first real CLI wiring of Codefly's existing permission primitives.
Do not describe it as already implemented reuse.
Dependencies and parallelism
Contract dependency:
Security-boundary dependency/interfaces:
F3 may develop in parallel with F2 after F1 freezes their shared interfaces.
F3 acceptance uses the real F2 broker, not a permissive stub.
F4 conformance waits for F1-F3.
Repository ownership
Primary:
codefly-dev/cliLinked Core changes stay as a checklist in this issue:
core/agents/manager/loader.go;core/runners/sandbox/;Likely CLI areas:
cmd/providerpkg/providercoordinator/state/approval/receipt packagesNo Stripe/Sentry/Resend branch is allowed in Core or CLI.
Product workflow
The founder path:
must:
PROJECT_OUTPUTthrough the host writer;Deliverables
1. Environment provider bindings
Add an environment-scoped
provider-bindingsmap:observe,managed,disabled);retaindefault,delete-ownedexplicit);Requirements:
spec;required;
2. Eight-command CLI
Implement:
Stable exits:
All commands support deterministic JSON where meaningful. No JSON/human output
may contain secret values or raw provider bodies.
--yessuppresses a prompt only after policy permits; it cannot mintauthority. There is no generic
--forcebypass.Local-state plan files are non-portable and bind exact workspace/state
generation. Cross-runner plan/apply requires H1 shared state and lock.
3. Principal acquisition and permission composition
Wire existing Core primitives into CLI provider operations:
policy.Principal;GatewayEvaluator;caveats;
WithProductionAdmission;The provider cannot choose the principal. The callback server uses the
spawn-time principal.
Authorize at:
Recheck revocation/policy before each remote effect and commit. A revoked grant
stops later actions and records partial/denied evidence.
Production admission rejects:
WithoutPrincipal;*orprovider:<name>/*mutation grants;--force.Break-glass is a distinct governed, receipted operation.
4. Hardened provider launch
Current generic agent spawn inherits
os.Environ()and current macOS sandboxdoes not enforce the proposed hostile-binary read boundary. Providers require
a new mandatory capacity profile.
Host requirements:
OP_*, proxy variables,*_KEY,*_SECRET, arbitraryCODEFLY_*, or HMAC scoped-auth signing material;Linux:
macOS:
(allow default)read behavior with a qualified provider readpolicy;
~/.codefly, secret/configuration locations, and unrelateduser files;
Windows is unsupported until it has equivalent enforcement.
If a platform cannot pass F4 hostile conformance, provider execution is
disabled there.
5. Host-driven per-action lifecycle
For each ordered action:
ApplyAction;The host coordinator is the sole retry owner.
A same-attempt retry requires the exact request/idempotency identity, qualified
vendor support/window, durable checkpoint, fresh authorization, and budget.
Non-idempotent
SENT_OUTCOME_UNKNOWNisUNCERTAIN, never blindly retried.6. Workspace state and ownership
Implement one
0600transactional store under a0700provider directory percanonical workspace, with:
(provider,type,remote-id) -> ownerindex;Requirements:
Remote resources default retained. URL/name/domain/email similarity never
adopts. Import requires exact ID and plan. Destroy deletes only exact
owned/adopted resources under
delete-owned.7. Projection writer and local sink
Implement host-only
PROJECT_OUTPUT:0600, fsync, atomic rename;Local sink:
Host-to-host projection of an existing runtime/build credential must not route
bytes through the provider.
Whole-configuration injection requires build-only credentials in a separate
configuration from runtime/browser values.
8. Endpoint and public-origin resolver
Create:
Requirements:
process.
9. Receipts and audit evidence
Wire signed receipts for provider operations:
Correlate:
Never include tokens, credentials, secrets, DSNs, raw bodies, emails, or
arbitrary vendor errors.
Support a local-authority path for founder dogfood without pretending a remote
SaaS Work Context exists, while retaining signed attributable evidence.
10. Doctor split
codefly doctor workspacestays bounded/local/no-agent and checks only:codefly provider doctoris explicit remote read-only work:Use
external_provider.*diagnostic codes to avoid existing secret-providerprovider_*collision.11. Readiness gates
Gate A — local dogfood:
Gate B — production observe:
Gate C — production mutation:
multi-user requirements.
Required tests
Permission matrix
--yescannot bypass escalation;Hostile spawn/platform
Seed parent environment with poison
OP_*, proxy, key, secret, Codefly, andHMAC values; provider sees none.
On Linux and macOS hostile provider attempts:
/proc/process environment where applicable;op, shell, curl, vendor CLI subprocess;All fail and produce safe evidence.
State/lifecycle
Writer/sink
Endpoint/CLI
Acceptance criteria
per-action Apply -> Project -> receipts -> Doctor.
admitted through existing Codefly policy primitives.
egress, and no workspace/secret access on Linux and macOS.
receipt terminal facts.
configuration injection without provider file access.
uncertain, and stale.
Explicit non-goals
Review findings discharged
This issue owns coordinator/permission/isolation/state/projection/CLI portions
of ADV-005, ADV-007/008, ADV-010, ADV-012 through ADV-014, ADV-018,
ADV-025 through ADV-031, ADV-038, ADV-040 through ADV-043, ADV-047, and the
associated state, writer, receipt, doctor, platform, and operability findings.