# Security

Source: https://modulify.ai/docs/api/security

Keep access tokens safe: where they belong, how little they should carry, and what to do when one leaks.

An access token acts as you. Anyone holding it can do whatever its scopes allow in the workspaces it reaches, so treat it like a password.

## Keep it on a server

Call the API from code you run: a server, a build job, a script on your own machine. Never put a token in a website, a mobile app or anything else that ships to other people's devices, where anyone can read it.

Keep the token out of your code itself. Read it from an environment variable or your platform's secret store, so it never lands in a repository.

```bash
export MODULIFY_TOKEN="mdf_mcp_..."
curl -X POST https://api.modulify.ai/v1/list_workspaces -H "Authorization: Bearer $MODULIFY_TOKEN"
```

## Send it only in the header

The token belongs in the `Authorization` header and nowhere else. Addresses are written to logs on the way, so a request with a token anywhere in its address is refused with a `400`, and that token should be treated as leaked: revoke it and create a new one. Modulify's own logs never keep a token, and a token that slips into an address is masked before anything is written.

## Give each job its own token

One token per script, service or person makes everything else easier:

- **Least scope.** Tick only the scopes the job needs. A reporting script needs read scopes, not `sites:delete`. The ten scopes that are off by default, the ones behind deleting, rewriting and revealing things, are worth a second thought each. See [Tokens and scopes](https://modulify.ai/docs/mcp/tokens-and-scopes#the-ten-that-are-off-by-default).
- **Fewest workspaces.** Narrow the token to the workspaces the job works in, so a mistake cannot reach the others.
- **Shortest life.** Pick the shortest expiry that fits the job. An expiry cannot be extended, so a token that should stop working on its own will.
- **A clear name.** Name the token after the job, so you know which one to revoke.

`credentials:reveal` deserves the most care. It is the only scope that returns live credentials in plain text, such as your environment variable values and the private storage key. Grant it for a one-off job and revoke the token afterwards.

## When a token leaks

Revoke it on the Tokens page from the row's menu with **Revoke token**. That takes effect at once, for the API and for any AI client using it, and every call after that gets a `401`. Then create a new token with the same settings and put it where the old one was.

Editing a token changes its name, scopes and workspaces for every client already using it, without a new value. To cut off one client, revoke its token. To narrow what a client may do, edit the token.

## Watch what tokens do

The Tokens page shows when each token was last used. Every call that reaches a method answers with an `X-Request-Id`, the id of that call in Modulify's records. Keep it in your own logs next to what your code was doing, so any call can be traced later.

## Next

- [Authentication](https://modulify.ai/docs/api/authentication) for scopes and workspaces.
- [Testing](https://modulify.ai/docs/api/testing) for trying calls with a read-only token.