Skip to content

[Provider plugins F3] Coordinator, permissions, hardened spawn, state, projections, and CLI #196

Description

@AntoineToussaint

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:

  1. load workspace/environment/binding;
  2. resolve/install the digest-bound provider;
  3. safely collect public inputs and secret references;
  4. acquire/validate the initiating principal;
  5. launch the provider through the hardened profile;
  6. validate offline;
  7. observe remotely through F2;
  8. resolve endpoints/origins;
  9. calculate a deterministic plan;
  10. authorize every exact action and request approval where required;
  11. execute one action at a time;
  12. persist checkpoint/state/capture before the next effect;
  13. execute PROJECT_OUTPUT through the host writer;
  14. emit signed receipts;
  15. run bounded provider doctor checks;
  16. print the product run command;
  17. 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:

  1. operation dispatch;
  2. every exact plan action;
  3. every broker request (F2 derives action/resource);
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockerenhancementNew feature or requesthighHigh-priority autonomous implementation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions