You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Create the Stripe reference provider, migrate SaaS Starter billing setup from
provider-specific shell logic to Codefly's provider lifecycle, and prove the
first complete local-dogfood vertical slice.
Stripe establishes the implementation baseline that opens Sentry and Resend
for parallel work. It does not declare the protocol fully stable; final
stability requires all three reference providers.
Do not implement Stripe-specific branches in Core or CLI. A generic defect
found by this issue is fixed behind the provider-neutral contract and added to
F4 conformance.
Repository ownership
This bootstrap issue is tracked in codefly-dev/module-saas-starter because
the final provider repository does not yet exist.
Deliverables:
create codefly-dev/provider-stripe;
implement provider code/tests/docs there;
update SaaS Starter generic billing configuration, dogfood, and setup shim;
make only provider-neutral bug fixes in Core/CLI with cross-linked PRs.
Operational prerequisites
Start immediately; do not create separate issues:
dedicated Stripe sandbox/test account isolated from personal/production
data;
management and runtime credential strategy;
opt-in CI/live-acceptance secret channel;
deterministic ownership prefix/metadata;
cleanup automation;
Stripe CLI installed only for explicit local-forwarded acceptance;
documented operator able to reveal/rotate a webhook secret in Workbench for
manual recovery testing.
No default CI depends on live Stripe availability.
Provider scope
Inputs
Define typed inputs:
API base selected through host origin admission;
explicit Stripe API version;
management credential handle;
runtime credential handle or explicit local shared-key opt-in;
account policy (sandbox/test, never inferred solely by provider);
callback endpoint reference and exposure mode;
webhook lifecycle;
desired event set;
existing webhook ID/import identity;
existing webhook-secret reference where applicable;
local-forwarder secret input;
description/ownership metadata policy.
Secrets are references/handles, never literals or provider RPC bytes.
Credential and mode boundary
Stripe Account does not expose livemode. The host must:
classify sk_test_, rk_test_, sk_live_, rk_live_ while resolving the
credential;
bind mode into credential handle, plan, authorization, and receipt;
reject local live credentials before a mutation;
cross-check livemode on brokered Stripe resource responses where present;
turn a host classification/response mismatch into blocked/uncertain safety
failure.
The provider receives only the host-attested mode.
Credential roles:
management: account read + webhook management;
runtime: only product billing operations required by SaaS Starter;
webhook verification: whsec_;
browser: none for hosted Checkout v0;
build: none.
Restricted-key scope categories are Dashboard-defined and not fully enumerated
in public docs. Qualify management/runtime restricted keys live rather than
claiming documentation proof.
An explicit shared management/runtime key is allowed only for local dogfood:
warning in plan;
dedicated policy opt-in;
receipt caveat;
never default production behavior.
Observed resources
stripe.account:
safe account ID/display subset;
charges/details readiness where relevant;
no false claim that Account contains livemode;
host-attested mode.
stripe.webhook-endpoint:
complete list/retrieve;
exact ID;
URL;
enabled event set;
endpoint API version;
status/disabled;
Codefly-owned metadata/description;
safe revision/created fields;
livemode;
secret presence/reference only.
Ignore unrelated remote/account/customer fields.
Field ownership and drift
Codefly owns:
callback URL derived from Codefly endpoint/ingress;
enabled event set, compared as a sorted set with Stripe wildcard semantics;
endpoint API version;
Codefly-namespaced metadata;
Codefly description marker;
active/disabled state only where explicitly configured.
Stripe owns:
endpoint ID/created/application;
webhook signing secret bytes;
unrelated metadata.
Changing endpoint API version is REPLACE, not UPDATE: Stripe does not expose
that field in update parameters. The plan must show:
destructive/replacement semantics;
new signing-secret effect;
old endpoint retention/delete ordering;
approval and rollback/manual recovery.
Remote manual changes to Codefly-owned fields produce drift. Foreign metadata
is ignored.
Ownership, discovery, and migration
On create, stamp supported Stripe metadata with safe Codefly identity:
workspace identity;
environment/binding;
resource address;
operation/prospective ID.
Never auto-adopt by URL.
If same-URL endpoints exist:
show candidates with exact ID, created time, events, version, status;
require operator selection/import by exact ID;
multiple matches are an unmanaged conflict;
no delete/update until imported/owned.
Stripe limits webhook endpoints per account; map quota failure and surface
cleanup/remediation without deleting unmanaged endpoints.
Managed lifecycle
Support:
Observe;
CREATE;
UPDATE allowed mutable fields;
REPLACE for API-version/write-once-secret changes;
exact-ID IMPORT;
exact-owned DELETE only through explicit destroy;
NOOP on repeated desired state;
MANUAL_ACTION for Dashboard secret reveal/rotation where appropriate.
Outcome
Create the Stripe reference provider, migrate SaaS Starter billing setup from
provider-specific shell logic to Codefly's provider lifecycle, and prove the
first complete local-dogfood vertical slice.
Stripe establishes the implementation baseline that opens Sentry and Resend
for parallel work. It does not declare the protocol fully stable; final
stability requires all three reference providers.
Dependencies
Foundation conformance gate:
Transitive foundation:
Do not implement Stripe-specific branches in Core or CLI. A generic defect
found by this issue is fixed behind the provider-neutral contract and added to
F4 conformance.
Repository ownership
This bootstrap issue is tracked in
codefly-dev/module-saas-starterbecausethe final provider repository does not yet exist.
Deliverables:
codefly-dev/provider-stripe;Operational prerequisites
Start immediately; do not create separate issues:
data;
manual recovery testing.
No default CI depends on live Stripe availability.
Provider scope
Inputs
Define typed inputs:
sandbox/test, never inferred solely by provider);Secrets are references/handles, never literals or provider RPC bytes.
Credential and mode boundary
Stripe Account does not expose
livemode. The host must:sk_test_,rk_test_,sk_live_,rk_live_while resolving thecredential;
livemodeon brokered Stripe resource responses where present;failure.
The provider receives only the host-attested mode.
Credential roles:
whsec_;Restricted-key scope categories are Dashboard-defined and not fully enumerated
in public docs. Qualify management/runtime restricted keys live rather than
claiming documentation proof.
An explicit shared management/runtime key is allowed only for local dogfood:
Observed resources
stripe.account:livemode;stripe.webhook-endpoint:livemode;Ignore unrelated remote/account/customer fields.
Field ownership and drift
Codefly owns:
Stripe owns:
Changing endpoint API version is
REPLACE, not UPDATE: Stripe does not exposethat field in update parameters. The plan must show:
Remote manual changes to Codefly-owned fields produce drift. Foreign metadata
is ignored.
Ownership, discovery, and migration
On create, stamp supported Stripe metadata with safe Codefly identity:
Never auto-adopt by URL.
If same-URL endpoints exist:
Stripe limits webhook endpoints per account; map quota failure and surface
cleanup/remediation without deleting unmanaged endpoints.
Managed lifecycle
Support:
Deletion defaults
retain.Idempotency and uncertain outcomes
Before POST:
Same-attempt replay is allowed only:
Live acceptance must verify Stripe replays the original webhook-create body,
including broker capture of the same secret, without duplicate endpoint.
Beyond the qualified replay window:
Response filtering and signing-secret capture
Manifest declares:
secretasCAPTURE_TO_SINK;The signing secret:
cassettes, Git, or command arguments;
Lost-response replay must capture/recover without duplicate.
Callback modes
local-forwarded:listen --forward-to;whsec_is distinct from registered endpoint secret and entersthrough safe host input;
public:existing:billing@1projectionPublic:
BILLING_PROVIDER=stripeSecret/reference:
Management key is never projected by default. Contract validation enforces
purpose.
Errors and rate limits
Map:
No raw Stripe error body is surfaced.
SaaS Starter migration
Replace
scripts/setup/stripe.shwith a non-writing compatibility shim afterplugin parity.
Safe legacy inputs may translate to Codefly input sources:
Flags without equivalent semantics hard-fail with exact guidance:
--provision-webhook;--skip-remote-validation;--force;The shim must:
rk_test_as well assk_test_through host classification;curl, write configuration, or manage remote resources;No URL-only adoption from the current script is retained.
Required tests
Tier 0
Tier 1 cassettes
Tier 3 live sandbox
Using dedicated account:
livemodemismatch handling;Tier 4 full dogfood
With real SaaS Starter backend/database:
Security invariants
Acceptance criteria
codefly-dev/provider-stripeexists with build/release/conformance.review/apply, run billing flows, and rerun with no diff.
assumed.
one-time secret.
endpoint.
data appears in plan/state/logs/diagnostics/receipts/cassettes/Git.
provisional until all three reference providers pass.
Explicit non-goals