Skip to content

fix(fly-io): redact add-on environment credentials - #943

Closed
mattespapier wants to merge 6 commits into
alchemy-run:mainfrom
mattespapier:fix/fly-addon-environment
Closed

mattespapier wants to merge 6 commits into
alchemy-run:mainfrom
mattespapier:fix/fly-addon-environment

Conversation

@mattespapier

Copy link
Copy Markdown
Contributor

Follow-up to #867, which made an add-on's password and publicUrl come back Redacted and left environment open. environment is the JSON object of variables Fly hands the app the add-on is attached to. For a Tigris storage add-on that is AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, so printing a createAddOn or addOn result prints the secret key.

Reproduction on main (dfd18f6d9):

const { addOn } = yield* createAddOn({ input: { type: "tigris", name: "files" } });
console.log(addOn.environment);
- { AWS_ACCESS_KEY_ID: "tid_…", AWS_SECRET_ACCESS_KEY: "tsec_…", BUCKET_NAME: "files" }
+ <redacted>     // Redacted.value(addOn.environment) returns the same object

pnpm vitest run packages/fly-io/test/protocol.test.ts -t "environment redacted whole" fails on main with expected false to be true.

- environment: unknown | null;
+ environment: Redacted.Redacted<unknown> | null;
  • scripts/convert.ts adds environment to the by-name sensitive members, next to password and publicUrl. In the GraphQL schema only AddOn has a member with that name, on every operation that returns an add-on (addOn, addOns, createAddOn, updateAddOn, resetAddOnPassword, organization.addOns).
  • scripts/generate.ts types a sensitive Document member as Redacted.Redacted<unknown>, since the value is a whole object, not a string. The value is wrapped whole; its keys are not walked.
  • Callers that read environment now unwrap it with Redacted.value. The type change is in the generated addons.ts.

Tests: a createAddOn case in lenient and strict mode with a Tigris-shaped environment; both fail on main with expected false to be true.
Live (2026-10-22 UTC): createAddOn for a Tigris add-on, then addOn and delete, in a Fly org with add-ons enabled. With this change the keys came back Redacted and non-empty.
Checked: pnpm vitest run packages/fly-io (38 passed), oxlint, oxfmt --check, and tsrs -b --noCheck false on fly-io and its test config.

Depends on #942, which makes core wrap a sensitive value that is an object, not only a string. Merge after it.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Benchmarks: PR acda5eb6e vs main 158a0caf1

  • ⚪ Bundle size 56.0 KB: +0.2% (+105 B), same as main
  • 🟢 Runtime speed 2.1 µs: −72.3% (−5.5 µs), smaller than main
  • ⚪ Runtime memory 647.8 KB: −0.9% (−5.9 KB), same as main
  • ⚪ Objects at import 964: −0.1% (−1), same as main
  • ⚪ Whole-SDK memory aws 38.7 MB (+0.1%), cloudflare 7.83 MB (−1.7%), gcp 24.0 MB (−0.0%)
  • ⚪ Repo size 427.4 MB tracked in 7,957 files, same as main (+21.9 KB). .generated-specs/ 0 B, src/services/ 402.4 MB, everything else 25.0 MB.

sdk-memory

bundle-programs

memory-programs

bundle memory
speed objects

Numbers

🟡 Timings moved, may be runner noise: import time on 2 (up to +33.9%, axiom); added latency (p50) on 7 (up to −81.9%, neon); import time on 4 (up to −36.5%, fly-io~FlyGraphqlProtocol); first call on 3 (up to −36.1%, neon)

Metric Change vs main Programs
Bundle (gzip) 1 worse 21
Import heap no change 10
Objects at import no change 10
Added latency (p50) ¹ 7 better 10
Import time ¹ 4 better, 2 worse 10
First call ¹ 3 better 10
Program Call Bundle (gzip) Import heap Objects at import Added latency (p50) Import time First call
aws s3.listBuckets 70.6 KB — — — — —
aws~awsJson1_0 dynamodb.listTables 63.5 KB — — — — —
aws~awsJson1_1 kms.listKeys 62.8 KB — — — — —
aws~awsQuery sts.getCallerIdentity 64.4 KB — — — — —
aws~ec2Query ec2.describeRegions 64.4 KB — — — — —
aws~restJson1 lambda.listFunctions 64.6 KB — — — — —
axiom v2.listDashboards 44.0 KB 632.0 KB 885 2.5 µs 12.2 ms (+33.9%) 🟡 4.0 ms
azure resources.ListTenants 50.5 KB (+0.2%) 🔴 — — — — —
cloudflare workers.listScripts 61.2 KB — — — — —
cloudflare~CloudflareProtocol ips.listIps 43.2 KB — — — — —
doppler doppler.listUsers 42.7 KB 656.3 KB 938 1.5 µs 8.5 ms 3.8 ms
doppler~DopplerPublicProtocol doppler.revokeCliAuth 42.4 KB 656.3 KB 938 0.7 µs 10.6 ms (+29.3%) 🟡 3.9 ms
fly-io machines.getRegions 57.3 KB 710.0 KB 1,082 3.7 µs (−64.5%) 🟢 13.0 ms 4.2 ms (−35.7%) 🟢
fly-io~FlyApiProtocol mpg.listUsers 57.0 KB 604.6 KB 979 2.1 µs (−72.6%) 🟢 9.4 ms (−32.9%) 🟢 3.5 ms
fly-io~FlyGraphqlProtocol addons.addOn 54.6 KB 616.7 KB 971 6.9 µs (−60.8%) 🟢 9.0 ms (−36.5%) 🟢 3.5 ms (−25.6%) 🟢
fly-io~SpritesProtocol sprites.createOrganizationToken 58.1 KB 632.6 KB 1,011 6.7 µs (−63.8%) 🟢 10.8 ms 4.9 ms
gcp storage_v1.listBuckets 44.3 KB — — — — —
github gists.list 45.9 KB 555.3 KB 816 2.1 µs (−77.5%) 🟢 8.9 ms (−27.8%) 🟢 5.1 ms
neon neon.listProjects 45.0 KB 717.5 KB 964 1.4 µs (−81.9%) 🟢 11.0 ms (−25.4%) 🟢 4.0 ms (−36.1%) 🟢
resend resend.listLogs 44.3 KB 582.2 KB 830 1.4 µs (−79.0%) 🟢 10.8 ms 4.5 ms
stripe stripe.GetFiles 44.3 KB — — — — —

PR acda5eb6e against main 158a0caf1 (main's cached run from 2026-10-28 16:58 UTC). 21 programs, measured in 97 s on 8 vCPU.

Package Tarball Unpacked Files
axiom 78.2 KB (+0.1%) 508.1 KB (+0.0%) 63
core 221.3 KB (+0.1%) 900.9 KB (−0.0%) 166
dev 395.2 KB (+0.2%) 1.8 MB (+0.2%) 201
doppler 91.6 KB (−0.0%) 711.7 KB 47
fly-io 164.3 KB (+0.0%) 974.0 KB (+0.1%) 71
github 2.0 MB (+0.0%) 17.4 MB (+0.0%) 318
neon 200.5 KB (−0.0%) 1.1 MB (+0.0%) 47
resend 62.8 KB (+0.0%) 446.4 KB (+0.0%) 47
Tracked files Size Change vs main Files
services 402.4 MB +359 B 2,192
in-tree-specs 130.7 KB ±0 B 4
patches 7.9 MB +435 B 3,706
handwritten 5.3 MB +21.0 KB 1,456
benches 9.5 MB ±0 B 189
other 2.2 MB +112 B 410
Total 427.4 MB +21.9 KB 7,957

What a checkout or worktree writes to disk, from git ls-tree (benches/repo-size/tree.ts). The dashboard's Repo size page has the full picture.

Effect alone: effect-minimal bundle 8.6 KB gzip, hand-written effect-http call 43.0 KB gzip; effect import 116.5 ms and 11.6 MB heap; bare mocked HTTP roundtrip 13.1 µs p50.

Bundled (from src/): resend, neon, github, fly-io, aws, cloudflare, gcp, azure, stripe, axiom, dev, doppler. Built and probed (from lib/): resend, neon, github, fly-io, axiom, dev, doppler. Changed in this PR: axiom, dev, doppler, fly-io, stripe. No target in targets.json: dev.

Job time: bundle 10.1 s, build: tsrs 2.7 s, build: bundle-lib 51.2 s, build: strip-lib-docs 0.3 s, build 54.2 s, size 1.8 s, runtime 23.3 s, providers 7.2 s.

¹ Timings run on a different runner than main's, so 🟡 marks a large move that may still be noise. Sizes, heap and object counts are stable. Offline: every call hits a canned in-memory response. Full suite: node benches/sdks/run.ts. Job log

github-actions Bot added a commit that referenced this pull request Oct 25, 2026
@alchemy-version-bot

alchemy-version-bot Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Install the packages built from this commit:

@distilled.cloud

pnpm install https://pkg.distilled.cloud/@distilled.cloud/acme/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/adyen/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/apache-superset/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/archil/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/argocd/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/auth0/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/aws/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/aws4signer/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/axiom/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/azure/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/boat-dev/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/celld/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/chronosphere/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/clerk/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/cloudflare/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/coinbase/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/coolify/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/core/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/customerio/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/datadog/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/daytona/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/digitalocean/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/discord/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/docker/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/doppler/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/elasticsearch/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/expo-eas/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/fly-io/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/forgejo/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/gcp/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/github/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/google-workspace/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/grafana/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/growthbook/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/gusto/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/hetzner/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/hostinger/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/huggingface/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/iceberg/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/infisical/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/inngest/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/intercom/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/kubernetes/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/launchdarkly/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/meilisearch/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/mercury/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/metabase/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/modal/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/modrinth/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/mongodb-atlas/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/neon/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/notion/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/okta/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/onepassword/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/opencode/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/ovh/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/paypal/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/plaid/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/planetscale/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/polar/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/porkbun/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/posthog/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/prisma/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/railway/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/redis-cloud/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/remote/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/render/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/resend/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/s2/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/sentry/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/slack/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/spacetimedb/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/squarespace/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/stackit/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/stripe/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/supabase/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/surrealdb/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/temporal/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/trigger-dev/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/turbopuffer/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/turso/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/typesense/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/unkey/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/vanta/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/vercel/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/whop/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/workos/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/xata/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/zendesk/pr:943:acda5eb
pnpm install https://pkg.distilled.cloud/@distilled.cloud/zerossl/pr:943:acda5eb

Published Oct 28, 2026, 7:37 PM UTC. Expires Nov 4, 2026, 7:37 PM UTC, extended while this pull request is open.

@mattespapier
mattespapier marked this pull request as ready for review October 25, 2026 18:26
Drops the .generated-specs edits, which main stopped committing (alchemy-run#933),
and keeps main's generatedAt stamp.
github-actions Bot added a commit that referenced this pull request Oct 28, 2026
@Mkassabov

Copy link
Copy Markdown
Collaborator

thanks for chasing this; closing in favour of #1012. spec fixes like sensitive marks go in packages/<pkg>/patches/, not as name-matching loops in convert.ts: a loop hides which shapes it touches, matches any future field with the same name, and the patch audit can't see it. #1012 moves password/publicUrl/buildToken into patches too.

@Mkassabov Mkassabov closed this Oct 30, 2026
@mattespapier

Copy link
Copy Markdown
Contributor Author

ty I will know the better solution later on!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants