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

# Authentication

> Create an OAuth client and authenticate the Uplink JavaScript SDK

Uplink authenticates with OAuth 2.0 client credentials. You create an OAuth client in Uplink Console, then pass its client ID and secret to the JavaScript SDK, which exchanges them for an access token on your behalf.

## Create an OAuth client

<Steps>
  <Step title="Open your project's settings">
    In Uplink Console, go to **Projects** and select the settings icon on the project you want to create credentials for.
  </Step>

  <Step title="Open the OAuth clients dialog">
    In the **OAuth Clients** section, select **Manage OAuth clients**, then **Create OAuth client**.
  </Step>

  <Step title="Configure the client">
    Give the client a name that identifies where it runs — for example `CI pipeline` or `Checkout automation`. Leave the token expiry fields at their defaults unless you have a reason to change them.
  </Step>

  <Step title="Save your credentials">
    Select **Create OAuth client**. Console shows the client ID and client secret, then asks you to confirm you've stored them.

    ```bash .env theme={null}
    UPLINK_CLIENT_ID=upoc_...
    UPLINK_CLIENT_SECRET=upocs_...
    ```
  </Step>
</Steps>

<Warning>
  The client secret is shown **once**, when you create the client. Copy it before closing the dialog. If you lose it, use **Rotate secret** to issue a new one — the old secret stops working immediately.
</Warning>

## Use the credentials

Pass your client ID and secret to `uplink.session()` as the first argument:

```typescript theme={null}
import uplink from '@uplink-code/uplink'

const session = await uplink.session(
  {
    clientId: process.env.UPLINK_CLIENT_ID,
    clientSecret: process.env.UPLINK_CLIENT_SECRET
  },
  {
    include: { ecdsa: true, ecdh: true }
  }
)

const client = await uplink.client.fromSession(session)
```

The same credentials object works for [`uplink.getSession()`](/api-reference/client#uplinkgetsession) and [`uplink.sessionDetails()`](/api-reference/client#uplinksessiondetails):

```typescript theme={null}
const credentials = {
  clientId: process.env.UPLINK_CLIENT_ID,
  clientSecret: process.env.UPLINK_CLIENT_SECRET
}

const session = await uplink.getSession(credentials, '<existing-session-id>')
const details = await uplink.sessionDetails(
  credentials,
  '<existing-session-id>'
)
```

<Note>
  The SDK handles the token exchange for you. It requests an access token the first time you make a call, reuses it across subsequent calls, and requests a new one before the old one expires.
</Note>

An OAuth client is granted a fixed set of permissions when you create it. If you'd rather a particular workload run with less than that, the credentials object also accepts a `scope` option that narrows what the resulting access token is allowed to do.

## Reuse an access token

If you'd rather hold the access token yourself — to share it across processes, or to inspect it — mint one with `uplink.token()` and pass the result anywhere credentials are accepted:

```typescript theme={null}
const token = await uplink.token({
  clientId: process.env.UPLINK_CLIENT_ID,
  clientSecret: process.env.UPLINK_CLIENT_SECRET
})

const session = await uplink.session(token, {
  include: { ecdsa: true, ecdh: true }
})
const details = await uplink.sessionDetails(token, session.sessionId)
```

<Warning>
  A token you hold yourself is **not** renewed for you. When it expires, calls made with it fail — call `uplink.token()` again with your client credentials to get a new one. Pass the credentials directly instead if you don't want to manage this.
</Warning>

## Keep your client secret safe

Treat the client secret like a password. Read it from an environment variable or a secrets manager, and never commit it or expose it in client-side code.

```typescript theme={null}
// ✓ Good: from the environment
const session = await uplink.session({
  clientId: process.env.UPLINK_CLIENT_ID,
  clientSecret: process.env.UPLINK_CLIENT_SECRET
})

// ✗ Bad: hardcoded
const session = await uplink.session({
  clientId: 'upoc_abc123...',
  clientSecret: 'upocs_def456...'
})
```

Create a separate client for each environment or workload so you can rotate or disable one without disrupting the others. You can rotate a secret, disable a client, or delete it entirely from the **OAuth Clients** dialog in Console.

## Next steps

<CardGroup cols={2}>
  <Card title="Sessions" icon="key" href="/sessions">
    Create and manage sessions
  </Card>

  <Card title="Client API" icon="plug" href="/api-reference/client">
    Explore the Client API reference
  </Card>
</CardGroup>
