feat(secrets): add apify secrets check + fail-fast on array-shaped environmentVariables#1265
Draft
DaveHanns wants to merge 1 commit into
Draft
feat(secrets): add apify secrets check + fail-fast on array-shaped environmentVariables#1265DaveHanns wants to merge 1 commit into
apify secrets check + fail-fast on array-shaped environmentVariables#1265DaveHanns wants to merge 1 commit into
Conversation
…environmentVariables
Two related issues currently make it easy to push an Actor whose
`@name` secret references are silently broken:
1. Nothing verifies that every `@name` referenced in
`.actor/actor.json`'s `environmentVariables` actually exists in the
local secrets store *before* `apify push` uploads and builds. The
check that does exist inside `transformEnvToEnvVars` is inline in the
push flow, gives no way to check standalone, and is easy to bypass
with `--allow-missing-secrets`.
2. `environmentVariables` is documented as a JSON object (key → value
map), but a common mistake — especially when copy-pasting the
API-wire shape — is to write it as an array of `{ name, value }`
entries:
"environmentVariables": [
{ "name": "MY_TOKEN", "value": "@MySecret" }
]
With that shape `transformEnvToEnvVars` iterates the array's
numeric indices, `isSecretKey` gets called on the entry object
(coerced to `[object Object]`), never matches, and the whole
`{ name, value }` object is passed through as an env-var value.
The build succeeds and the deployed Actor gets literal
`[object Object]` at runtime. There is no error at any point.
Changes
-------
- Add `apify secrets check` command that scans `.actor/actor.json`
for every `@name` reference, verifies each resolves to a locally
stored secret, and validates that `environmentVariables` is an
object. Supports `--json` for scripting and `--dir` to point at an
Actor directory. Exits non-zero (InvalidActorJson) on any failure.
- Add `validateEnvironmentVariablesShape` and `findSecretReferences`
helpers in `src/lib/secrets.ts`. Both are used by the new command
and by `apify push`'s preflight.
- Wire the shape check into `apify push` preflight (before any files
are uploaded), so the array-shaped mistake fails fast with a
message that shows exactly how to fix it, instead of silently
building a broken Actor.
- Unit tests for both new helpers, covering the array/scalar/
non-string-value failure modes and the reference-extraction
behaviour.
Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related issues currently make it easy to push an Actor whose
@namesecret references are silently broken, and there is no CLI command to check them before pushing:No standalone way to verify secret references. Nothing checks that
@namereferences in.actor/actor.jsonresolve to locally-added secrets untilapify pushis deep insidetransformEnvToEnvVars, and even that check can be silenced with--allow-missing-secrets.Array-shaped
environmentVariablesare silently accepted.environmentVariablesis documented as a JSON object (key → value map), but a common mistake — especially when copy-pasting from the Apify API wire shape or from other tooling — is to write it as an array of{ name, value }entries. The CLI accepts that shape without complaint and ships a build where every env-var value is the literal string[object Object].This PR adds an
apify secrets checkpreflight command and wires the shape check intoapify pushso both mistakes fail fast with actionable errors.Reproducer for the silent-array bug
Given
.actor/actor.json:{ "actorSpecification": 1, "name": "test-actor", "version": "0.0", "environmentVariables": [ { "name": "MY_TOKEN", "value": "@mySecret" } ] }apify pushtoday completes without any warning. On the platform, the build's env vars contain a single entry whose value at runtime is literally[object Object]. Tracing throughsrc/lib/secrets.ts:transformEnvToEnvVarscallsObject.keys(env)on the array, iterating'0','1', ...env[key]is an{ name, value }object.isSecretKey({ name, value })coerces the object to[object Object], which does not match^@., so the "secret" branch is never taken.envVars.push({ name: '0', value: {name, value} }).Changes
New
apify secrets checkcommand (src/commands/secrets/check.ts) — scans.actor/actor.jsonfor every@namereference, verifies each resolves to a locally stored secret, and validates the shape ofenvironmentVariables. Supports--jsonfor scripting and--dirfor pointing at another Actor directory. Exits non-zero on any failure.validateEnvironmentVariablesShapeandfindSecretReferenceshelpers insrc/lib/secrets.ts. Both are used by the new command and byapify push's preflight. Rejects arrays, scalars, and objects with non-string values, and emits a diff-style error message that shows the exact fix.apify pushpreflight — the shape check now runs afteruseActorConfigand before any upload. The push fails fast withCommandExitCodes.InvalidActorJson, so the agent/user sees the error immediately instead of a broken deployed Actor.Unit tests for both new helpers, covering array / scalar / non-string-value failure modes and reference extraction.
Example error output
Test plan
pnpm test:local— unit tests forvalidateEnvironmentVariablesShapeandfindSecretReferencesall pass (15/15 intest/local/lib/secrets.test.ts).tsc --noEmit— clean.oxlint --type-awareon all touched files — clean.oxfmt --checkon all touched files — clean.environmentVariablesand runapify push— should fail with the object-vs-array error before any upload."environmentVariables": { "TOKEN": "@doesNotExist" }and no local secret fordoesNotExist, then runapify secrets check— should exit non-zero and print the "add" command.@namereferences present locally,apify secrets checkshould print the green "all N secret reference(s) resolve" message.Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.