Skip to content
OpenComputer

Secrets and variables

A session reads secrets and variables as environment variables; secrets are entered in a private Slack form and redacted from its posts

EnteredShown in SlackRedacted
SecretIn a private Slack formNoYes
VariableIn a messageYesNo

Slack stores messages and the model reads them, so a secret never goes in a message.

Secrets need SP_STORE_KEY set on the gateway; without it the commands answer Secrets are not available: the gateway has no SP_STORE_KEY.

Set a secret

Ask for the form

Send !secret NAME, or !secret NAME file for a value that should arrive as a file. The gateway answers with a message only you can see, holding an Enter NAME button.

The answer to !secret STAGING_DB_URL, visible only to the sender, with an Enter STAGING_DB_URL button

Fill in the form

Enter the value (several lines allowed, up to 3000 characters), choose a scope under Available to, and tick Provide as a file if needed.

The Set a secret form: Name, Value, Available to with three scopes, the Provide as a file option, and Cancel and Save

Save

The value goes from Slack to the gateway, not through the conversation or the model. Running sessions in scope receive it at once.

ActionHow
List names per scope (never values)!secret
Remove from a scope!secret rm NAME [session|me|workspace]
Session asks for a credentialThe gateway posts This session needs $NAME, the reason, and a button in the thread. Anyone on the people list can fill in the form. A runner can ask 10 times.
A session asking for a secret in its thread: This session needs $STAGING_DB_URL, the reason, and an Enter STAGING_DB_URL button

Every form of the command: Slack commands.

Names

Names match ^[A-Za-z_][A-Za-z0-9_]{0,63}$. Refused names:

  • PATH, HOME and similar
  • names starting with SP_, CLAUDE, ANTHROPIC_, GIT_, LD_, DYLD_ or BASH_FUNC
  • proxy and CA bundle variables

Scopes

ScopeIn the formIn commandsWhich sessions receive itLifetime
SessionThis session onlysessionThe session of the thread the form was opened fromDeleted 30 days after the session was last active
PersonJust memeEvery session the person ownsUntil removed
WorkspaceWorkspaceworkspaceEvery sessionUntil removed. Only admins see the option and can set or remove it; see People.
  • When the same name is set in more than one scope, the narrowest wins.
  • A secret you set with Just me in someone else’s thread does not reach that session: a session receives the person-scope secrets of its owner.
Not in the open-source code yet (runner isolation). Each session’s runner will run in its own rootless container with its own secrets. Today all sessions on the computer run as one Unix user, so a session can read another session’s secret files and process environments, and so can every person who can direct a session. The form says so.

In the session

FormWhat the session gets
Default$NAME holds the value.
Provide as a file$NAME holds the path of a file with the value. Use for a service account JSON, a kubeconfig or a private key.

A secret set, changed or removed during a turn takes effect in the next shell command the session runs.

The gateway stores secrets in its SQLite database, encrypted with AES-256-GCM under a key derived from SP_STORE_KEY.

Redaction

The runner replaces every secret value it knows with [secret:NAME] in everything it posts to Slack, and refuses to post a file or card that contains one. It does not cover:

  • a value shorter than 6 characters
  • a line of a multi-line value quoted on its own, when the line is shorter than 16 characters
  • a value that is encoded, split, reversed or drawn in an image
  • a value sent anywhere other than Slack: a commit, a request, a log on the computer

Variables

!var NAME value [session|me|workspace] sets a variable and !vars lists names and values. Every form of the command: Slack commands.

  • The default scope is the session of the thread the command is sent in, and me where there is no session.
  • Scopes, name rules, the workspace admin rule and the 3000-character limit are the same as for secrets.
  • A variable cannot replace a secret of the same name in the same scope; a secret can replace a variable.
  • When a name or value looks like a credential, the gateway does not keep it until Set it anyway is pressed.
Two !var commands and their answers, visible only to the sender: one variable set, one not set because its name sounds like a credential, with a Set it anyway button