gitstalk
Docs: Secrets and variables

Secrets and variables live

Secrets hold credentials. Variables hold plain configuration. Workflows and automations read them as ${{ secrets.NAME }} and ${{ vars.NAME }}.

Secret

Write-only and encrypted at rest. Settings lists its name, never its value. It is masked in logs. Use it for tokens, keys and passwords.

Variable

Plain configuration such as an account id, a region or a URL. Anyone with a role on the repository can read its value, and logs print it. Never put a credential in one.

Add a secret

  1. Open the repository's settings

    Go to Settings, then Secrets and variables. You need the maintain role or to own the repository. Everyone else with a role sees names only.

  2. Name it and paste the value

    Names use letters, digits and underscores, up to 100 characters, and may not start with GITHUB_. Names are stored in upper case. Saving a name that exists replaces its value.

  3. Name it in the workflow

    .github/workflows/deploy.yml
    - run: npx wrangler deploy
      env:
        CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }}

    A run gets only the secrets its workflow names.

The repository screen

Actions minutes42 of 100 minutes used in October. Each job stops after 60 minutes.
CLOUDFLARE_API_TOKEN •••••••••••• updated 3 days ago by @ada Pre-land: off
TEST_DATABASE_URL •••••••••••• updated 2 weeks ago by @ada Pre-land: on
NameFor example CLOUDFLARE_API_TOKEN
NPM_TOKEN
ValueSaving a name that exists replaces its value.
••••••••••••
Available to pre-land checks Pre-land checks run the code in a bean before anyone has reviewed it. Any test in such a bean can read this secret and send it anywhere. Turn it on only for values that are safe to leak, such as a test database.
Off
Save secret
REGISTRY_TOKEN org •••••••••••• from @acme, updated 1 month ago Read-only
Your own secrets, the add form, and below them the org entries this repository inherits, read-only, each marked with where it comes from.

Variables sit on the same page with the same form, minus the mask and the pre-land toggle. Inherited org entries show a variable's value. An org entry that your repository overrides stays listed and says so.

The organization screen

Org owners and admins manage org secrets and variables in the org's Settings, then Secrets and variables. Other org members can read names. Each entry chooses which repositories it reaches.

Repository access All repositories, private and internal repositories, or selected repositories.
Selected: api, web
REGISTRY_TOKEN •••••••••••• selected: api, web Delete
The org page also lists a log of changes. "Private" includes internal repositories.

Precedence: a repository entry with the same name beats the org entry, as on GitHub.

Who gets which secrets

A secret is released only to code you trust. Pick the row for how the run started.

Run started by Secrets released Job token
The stalk moving (a push to main), Run workflow, a schedule The ones the workflow names. This is how deploys work. As the workflow's permissions say
An automation, started by a bean event Only the secrets marked available to pre-land checks May push bean/* if beans: write
An automation, scheduled or run by hand The ones the automation names in secrets: As above
A pre-land workflow run of a bean pushed by an agent session, a deploy token or a collaborator below maintain planned None, unless the secret is marked available to pre-land checks Read-only

Masking

Every secret value a job may read is replaced with *** in the log before the log is stored or streamed. The base64 and URL-encoded forms are masked too, and so is the job token. Values shorter than three characters are not masked, as on GitHub. Masking is a net, not a vault: do not print secrets on purpose.

Protect the workflow files

A workflow that holds a secret is code, and an agent can change code. List the workflow folder in protected-paths of .gitstalk/checks.yml so only maintainers and the owner can change it:

.gitstalk/checks.yml
protected-paths:
  - .github/**

A stalk workflow still runs your package.json scripts, which agents wrote, with its secrets, as auto-merge does on GitHub. Asking for approval before secrets are released is planned.

From an agent beta

An agent session sees names and sets values through two tools. The tool surface was renamed on 2026-10-14 (actions_secret_* and actions_variable_* became actions_config_*), so a server you connected earlier may still show the old names.

Tool What it does Needs
actions_config_list Secret names with where each comes from and who updated it, never values. Variables with their values. Any role that reads the repository
actions_config_set Stores a secret or a variable. A secret is write-only. The secrets scope, ticked on the consent page, and the maintain role. An org entry needs an org owner or admin.
actions_config_delete Deletes one, only when you asked. Workflows that read it get an empty value. Same as set
  • The secrets scope is never pre-ticked on the consent page. A session without it never sees the set and delete tools.
  • Prefer adding the secret yourself. If you give the value to an agent, it passes through the agent and its model provider. A missing secret is best handled by asking you to add it in Settings. The agent only stores a value you gave it for that name.
  • The audit log names the secret, you and the agent's client, as via <client> (MCP).
  • An org entry set this way starts out reaching only the repository the agent named.

Good to know

  • Deleting a repository deletes its secrets and variables.
  • Variables named GITSTALK_DEPS_CACHE, GITSTALK_DEPS_SNAPSHOT_MAX and GITSTALK_NPM_AUDIT switch Gitstalk's own job behaviour. See Environment variables.
  • Secrets are encrypted at rest with a key the deployment holds. A self-hoster sets it. See Self-hosting.

Sources