# Authentication
Source: https://docs.aden.space/docs/developers/sdk/authentication

Pick the right auth mode. API keys for backends, Supabase tokens for user apps.
The SDK supports three ways to authenticate, in order of precedence:

1. `apiKey`: static team API key.
2. `getToken`: async function that returns a token per request.
3. No auth, only public endpoints like `/health` will respond.

All of them send the token as `Authorization: Bearer <token>`.

## Team API keys [#team-api-keys]

Use these for server-to-server code, cron jobs, DAW plugins, and integrations
where the credential belongs to a team, not an end user.

```ts
const aden = createAdenClient({
    apiKey: process.env.ADEN_API_KEY,
})
```

* Format: `aden_live_<random>`.
* Scope: a single team. The backend resolves the team from the key. You
  don't need to pass `teamId` for scoped SDK endpoints.
* Permissions: read-first. Write endpoints check the key's scopes.
* Rate-limited by the team's plan. See [Rate limits](/docs/developers/api/rate-limits).

## Supabase session tokens [#supabase-session-tokens]

Use these for apps where a real person logs in. You re-use the Supabase access
token the user already has, so Row Level Security policies apply.

```ts
import { createClient } from '@supabase/supabase-js'
import { createAdenClient } from '@adenspace/sdk'

const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)

export const aden = createAdenClient({
    getToken: async () => {
        const { data } = await supabase.auth.getSession()
        return data.session?.access_token ?? null
    },
})
```

`getToken` runs on every request, so refreshes and sign-outs are picked up
automatically.

## Custom providers [#custom-providers]

`getToken` is just an async function. Plug it into any auth stack:

```ts
const aden = createAdenClient({
    getToken: async () => {
        const token = await auth0.getAccessTokenSilently({
            audience: 'https://www.aden.space/api/v1',
        })
        return token ?? null
    },
})
```

Return `null` to make an unauthenticated request.

## What each mode can do [#what-each-mode-can-do]

| Scenario                   | API key                | Session token    |
| -------------------------- | ---------------------- | ---------------- |
| Read tracks / albums       | ✅                      | ✅                |
| Write tracks / albums      | ✅ (with scope)         | ✅                |
| Team management            | ❌ (session only)       | ✅                |
| `auth.me`, `user.*` routes | ❌                      | ✅                |
| Cross-team reads           | ❌ (scoped to one team) | ✅ (user's teams) |
| Rate limit bucket          | Team plan              | Per user         |

## Storing keys safely [#storing-keys-safely]

* **Never** expose API keys in client-side code. Shipping them to a browser
  or mobile app leaks them to everyone who can open devtools.
* For user-facing apps, use [Supabase tokens](#supabase-session-tokens) or
  issue short-lived tokens from your own backend.
* Rotate keys from **Settings → API Keys** if you suspect exposure. The
  old key stops working immediately.