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

# Authenticate Where Your Agent Runs

> Put a difyctl session on the server or container where your agent runs, so it can call Dify apps unattended

Your agent never logs in. It reuses the `difyctl` session on the machine where it runs, acting as whoever signed in: an account user, or an external SSO user limited to their permitted apps. How you get a session there depends on the machine:

* **Your own machine**: sign in ([account](/en/3.11.x/develop/cli/account-users/authenticate) or [SSO](/en/3.11.x/develop/cli/sso-users/authenticate)) and you're set.
* **A server or VM you can log into**: sign in on it (Option 1).
* **A container, CI runner, or prebaked image**: copy a session in (Option 2).

## Option 1: Sign In on the Machine

Sign in on the target machine as the identity the agent should act as. The agent inherits everything that identity can reach: an account user's workspace apps, or the apps an external SSO user is permitted to run.

Use the [console API URL](/en/3.11.x/deploy/advanced-configuration/environment-variables#console_api_url) for `--host`.

Pass `--no-browser` when the machine has no browser:

```bash theme={null}
difyctl auth login --host https://dify.example.com --no-browser
```

`difyctl` prints a one-time code and a verification URL. Open the URL on any device, sign in, and enter the code. The session is written to the machine the moment you approve.

Confirm it landed:

```bash theme={null}
difyctl auth whoami
```

```text theme={null}
<your-email> (<your-name>)
```

An external SSO user sees `<your-email> (external SSO, issuer: <your-identity-provider>)` instead.

## Option 2: Copy a Session You Already Have

Use this when you can't sign in on the target itself, like a prebaked image or an ephemeral container.

<Steps>
  <Step title="Sign in on a machine without an OS keychain">
    Use a headless Linux server or a container. Without a keychain, `difyctl` saves the token to `tokens.yml` in the config directory, making the entire directory portable.

    Before copying, confirm `tokens.yml` exists in the config directory (`~/.config/difyctl` by default). If it's missing, a keychain captured the token instead, and there's no supported way to export it. Sign in directly on the target with [Option 1](#option-1-sign-in-on-the-machine).
  </Step>

  <Step title="Copy the config directory to the target">
    After copying, point `difyctl` at it with [`DIFY_CONFIG_DIR`](/en/3.11.x/develop/cli/reference/environment-variables). For a container, mount the directory at runtime instead of baking it into the image:

    ```bash theme={null}
    docker run \
      -v /path/to/difyctl-config:/config:ro \
      -e DIFY_CONFIG_DIR=/config \
      your-agent-image
    ```

    `tokens.yml` is a live credential. Keep its `0600` permissions and keep it out of images and version control. The mount is read-only because an agent that only runs apps never writes to the config directory.
  </Step>
</Steps>

## When the Session Expires

A server-expired or revoked session surfaces as exit code 4 with `error.code` `auth_expired`. The agent can't recover on its own: a new session takes a person approving the sign-in, the same one-time-code step as Option 1.

So it should stop and surface the failure for a human to sign in again, not retry. See [Handle Errors and Retries](/en/3.11.x/develop/cli/integrate-agents/error-handling-and-retries-for-agents#branch-on-the-exit-code) for how to branch on it.

To revoke a session you suspect is compromised, run [`auth devices revoke`](/en/3.11.x/develop/cli/reference/auth-and-contexts#revoke-sessions) from any signed-in machine.
