> ## Documentation Index
> Fetch the complete documentation index at: https://docs.artil.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Store and use credentials

> Store API keys and passwords, then load them into Claude Code, Pi, Hermes, or a .env file.

An agent account's secret stores an API key, password, token, or one-time
password. Sign in as the agent that will use it. With an account login, `list`,
`set`, and `remove` take `--agent <agent>`, but `copy`, `code`, `link`, and
`pull` need the agent's own login.

## 1. Choose where the credential belongs

Before storing it, check the agent and workspace with `artil auth status`.

<Note>
  Any workspace member can add, replace, and remove an agent's secrets. Only the agent's own login
  can read their values.
</Note>

Store credentials meant for this agent.
Names become environment variable names, such as `SERVICE_API_KEY`.

## 2. Store the value

In a terminal, omit the value to enter it without showing what you type:

```bash theme={null}
artil secrets set SERVICE_API_KEY
artil secrets list
```

Check that the list includes `SERVICE_API_KEY`. It shows whether a person or
the agent last set the value, and when, keeping the value hidden. Running `set`
again replaces it.

<AccordionGroup>
  <Accordion title="The credential comes from another command">
    Pipe that command's output directly into `artil secrets set SERVICE_API_KEY`.
    This keeps the key out of the command text and shell history.

    If that command produces JSON, select a field with `--json-path .token`
    or a nested path such as `--json-path '.data.items[0].key'`.

    Add `--json` for JSON output. With this flag, supply or pipe the value;
    the CLI returns an error if it would need to prompt for one.
  </Accordion>

  <Accordion title="The name or value is rejected">
    Names use up to 128 letters, digits, and underscores and cannot begin with
    a digit. Names that change how programs run are reserved. These include
    `PATH`, `HOME`, names starting with `ARTIL_`, `CLAUDE_`, `HERMES_`, `GIT_`,
    or `LD_`, and names ending in `_BASE_URL`, such as `OPENAI_BASE_URL`.

    Values must contain 1 to 32,768 characters and no NUL characters. A
    trailing line break is removed. An agent holds at most 200 secrets.
    Multiline values are accepted, but some clients cannot load them.
  </Accordion>

  <Accordion title="The credential is a password or a one-time password">
    Add `--kind password` for a password. For a one-time password, store the
    setup key the service shows with `--kind otp`, or read its QR code from an
    image with `--qr`:

    ```bash theme={null}
    artil secrets set SERVICE_OTP --kind otp
    artil secrets set SERVICE_OTP --qr ./qr.png
    ```

    The secret holds the `otpauth://` link, and `artil secrets list` shows each
    secret's kind. Print the current code to sign in with:

    ```bash theme={null}
    artil secrets code SERVICE_OTP
    ```
  </Accordion>
</AccordionGroup>

## 3. Choose where to use it

Linking copies **all of the agent's secrets** to the client or file you choose.
Link only places that should have access to all of them.
`artil init` already links the local client it connects, so check
`artil secrets list` before adding another link. The Claude Code plugin and
Pi package do not link secrets as part of their installation.

<Tabs>
  <Tab title="Claude Code">
    ```bash theme={null}
    artil secrets link claude-code
    ```

    This installs a session-start hook in your **user-level Claude Code
    configuration**, which applies across projects. Claude's Bash commands
    load the linked agent's secrets from a private script. Linking another
    agent here replaces the previous link.

    Start a new Claude Code session after first linking. Programs launched by
    its Bash tool can then use `$SERVICE_API_KEY` without putting the value
    into the conversation.
  </Tab>

  <Tab title="Pi">
    ```bash theme={null}
    artil secrets link pi
    ```

    This adds the `artil-secrets` extension to `~/.pi/agent/extensions`, which
    applies across projects. Pi's bash commands load the linked agent's
    secrets from a private script. Linking another agent here replaces the
    previous link.

    Run `/reload` in open Pi sessions after first linking. Programs launched by
    its bash tool can then use `$SERVICE_API_KEY` without putting the value
    into the conversation.
  </Tab>

  <Tab title="Hermes">
    ```bash theme={null}
    artil secrets link hermes
    ```

    The CLI writes a section in `.env` under `$HERMES_HOME` (default
    `~/.hermes`) and adds the names to `terminal.env_passthrough` in
    `config.yaml`. Hermes must already be set up there. Restart a running
    Hermes process if it already loaded its environment.
  </Tab>

  <Tab title="Project .env">
    Ignore the destination in Git before linking it:

    ```bash theme={null}
    artil secrets link ./.env
    ```

    The CLI writes its own section in the file. Your application must load
    the file to use the values. The CLI rejects files Git could commit unless
    you add `--force`, and keeps existing assignments outside its section. It
    reports and skips conflicting names and values the file cannot store.
  </Tab>
</Tabs>

Check that `artil secrets list` shows the client or file you linked. A failed
`link` is not recorded, so fix the error and run `artil secrets link <place>`
again. `artil secrets pull` refreshes existing links, such as after you fix
names that were left out. Use the saved key to make a request to the service
and check that it succeeds.

Programs that receive a secret through their environment can read its value.
Keep those values out of logs and conversations.

## Keep it working

<AccordionGroup>
  <Accordion title="Refresh a changed credential">
    When you are signed in as the agent, `set` and `remove` refresh its linked
    destinations on this machine. After changing a value with an account login,
    in the app, or on another machine, run this as the agent:

    ```bash theme={null}
    artil secrets pull
    ```

    Run `pull` each time you need changes made elsewhere. Claude Code's hook
    and Pi's extension also try to refresh secrets when a session starts. Once
    they are active, the next Bash command can use values updated by `pull`. Restart
    other programs that read their environment only at startup.

    If storing succeeds but updating a linked destination fails, the command
    reports the error and exits with a nonzero status. Fix the link and pull again.
  </Accordion>

  <Accordion title="Paste a credential into a form">
    ```bash theme={null}
    artil secrets copy SERVICE_API_KEY
    ```

    The command copies the value to your clipboard without printing it. It
    needs a clipboard tool: `pbcopy` on macOS, or `wl-copy`, `xclip`, or `xsel`
    on Linux.
  </Accordion>

  <Accordion title="Remove a local link">
    ```bash theme={null}
    artil secrets unlink ./.env
    ```

    Replace `./.env` with the linked destination, such as `claude-code`, `pi`,
    or `hermes`. Unlinking removes the values the CLI wrote there and leaves the secret
    stored in Artil. Stop processes that already loaded those values if they
    should no longer have access.
  </Accordion>

  <Accordion title="Delete or revoke a credential">
    ```bash theme={null}
    artil secrets remove SERVICE_API_KEY
    ```

    This deletes the stored value from Artil. When you are signed in as the
    agent, it also refreshes this machine's links; otherwise, the agent runs
    `artil secrets pull`. Other machines need to refresh their copies.
    Deleting a stored API key does not revoke it at the service that issued
    it; revoke it there to end access.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.