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
| Entered | Shown in Slack | Redacted | |
|---|---|---|---|
| Secret | In a private Slack form | No | Yes |
| Variable | In a message | Yes | No |
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.
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.
Save
The value goes from Slack to the gateway, not through the conversation or the model. Running sessions in scope receive it at once.
| Action | How |
|---|---|
| List names per scope (never values) | !secret |
| Remove from a scope | !secret rm NAME [session|me|workspace] |
| Session asks for a credential | The 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. |
Every form of the command: Slack commands.
Names
Names match ^[A-Za-z_][A-Za-z0-9_]{0,63}$. Refused names:
PATH,HOMEand similar- names starting with
SP_,CLAUDE,ANTHROPIC_,GIT_,LD_,DYLD_orBASH_FUNC - proxy and CA bundle variables
Scopes
| Scope | In the form | In commands | Which sessions receive it | Lifetime |
|---|---|---|---|---|
| Session | This session only | session | The session of the thread the form was opened from | Deleted 30 days after the session was last active |
| Person | Just me | me | Every session the person owns | Until removed |
| Workspace | Workspace | workspace | Every session | Until 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.
In the session
| Form | What 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
mewhere 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.