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

# Step 1: Authenticate

> Authenticate to the CryptoHub REST API with dual login and obtain a bearer token.

CryptoHub enforces **dual login**: a single administrator is not fully authenticated until a second administrator has also logged in within the same session. The two logins share one cookie jar, and the bearer token is only minted once the session is fully logged in.

<Steps>
  <Step title="Encode the password">
    The password is sent **base64-encoded** in the `password` field. Generate it once:

    ```bash lines wrap theme={null}
    PW=$(printf 'your-admin-password' | base64)
    ```
  </Step>

  <Step title="Log in with dual login">
    Log in as `Admin1`, then `Admin2`, writing to a shared cookie jar (`-c` writes, `-b` reads):

    ```bash expandable lines wrap title="Dual login" theme={null}
    B=https://localhost:8443
    CJ=./ch-admin.cookies

    for U in Admin1 Admin2; do
      curl -sk -c "$CJ" -b "$CJ" -X POST "$B/home/v1/login" \
        -H 'Content-Type: application/json' \
        -d "{\"authCredentials\":{\"username\":\"$U\",\"password\":\"$PW\"},\"authType\":\"userpass\"}"
    done
    ```

    The first login responds with `fullyLoggedIn: false`; after the second login the session is complete:

    ```json expandable lines wrap title="Second login response (truncated)" theme={null}
    {
      "message": "Success",
      "response": {
        "fullyLoggedIn": true,
        "hardened": false,
        "management": true,
        "perms": ["CertManage:Inject", "Crypto:Decrypt", "Keys", "..."]
      }
    }
    ```
  </Step>

  <Step title="Mint a bearer token">
    Now exchange the fully logged-in session for a bearer token:

    ```bash lines wrap title="Mint the bearer token" theme={null}
    TOKEN=$(curl -sk -c "$CJ" -b "$CJ" "$B/home/v1/login/token" \
      | python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')
    ```

    ```json lines wrap title="GET /home/v1/login/token response (truncated)" theme={null}
    {
      "message": "Success",
      "status": "Success",
      "token": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjI1NDQ5IiwidHlwIjoiSldUIn0.eyJ..."
    }
    ```

    For the remaining steps, send the token as a bearer header. Keep the cookie jar too, as some hosts accept either:

    ```bash lines wrap theme={null}
    AUTH=(-H "Authorization: Bearer $TOKEN")
    ```
  </Step>
</Steps>

<Check>
  A subsequent read-only call such as `GET /api/v2/x509/cert-profiles/stubs` should return HTTP `200` with `"success": true`. If you receive HTTP `401` or `"errorCode": "InvalidAuthToken"`, the token has expired; repeat this step to mint a fresh one.
</Check>
