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

# API key expiry and allowed addresses

> Give API keys and personal tokens an expiry, see when they were last used, cap how long keys can live, and limit the addresses a key may be used from.

Free plan

API keys and personal tokens outlive a sign-in, so they carry their own limits. Everything on this page is optional, and nothing about an existing key or token changes: a key with no expiry and no address list works exactly as before.

## Set an expiry

When you create an API key under **Settings**, **API Keys**, choose 30, 90 or 365 days, a date, or never. A personal token on **Account** offers the same choices, with one difference: **no date** still ends the token 365 days after it was made, which has always been the rule for personal tokens. A personal token never lasts longer than a year.

* A key or token stops working at the second it expires.
* An expiry in the past is refused.
* The REST API accepts `expires_at` (ISO 8601) the same way.
* A key created by another key can never outlive it.

### Rotate a key

Rotating a key (`POST /api/api_keys/:id/rotate`) makes a new key whose **original lifetime is counted from the day of the rotation**, not the old absolute date. A key rotated on its last day, or after it expired, is not born expired. A key with no expiry rotates to one with none, and a short key stays short: a two hour key rotates to a two hour key. Scopes and allowed addresses carry over.

Rotating over the REST API with a key rather than a person's token is limited like creating one:

* A key can rotate itself, or another key only when it holds every scope that key has and is allowed from every address that key is allowed from. A key with no list counts as wider than any list.
* The new key never outlives the key that rotated it, and a key that another key made is cut to that key's expiry while that key still lives.
* A refused rotation changes nothing.

### Limit how long keys can live

An org admin can set the longest life an API key may have under **Settings**, **Security**, from 1 to 730 days.

* A key created with no expiry then gets that date, and a later expiry is refused with a sentence.
* Rotation cuts a longer lifetime down to the limit instead of refusing.
* Keys that already exist are not changed. The ones above the limit are marked **No expiry, above your policy** or **Longer than your policy** on the **API Keys** tab.
* The limit applies to API keys, not to personal tokens, which never exceed 365 days.
* Over MCP and the configuration API the field is `api_key_max_days` (null for no limit). It needs the user token of an org admin: an API key is refused, and Terraform reads it and never writes it.

### Expiry reminders

A daily job emails the person who created a key 14 days and again 3 days before it expires. The owner of a personal token gets the same.

* **A personal token with no date of its own gets no reminder.** It ends 365 days after it was made without an email, so pick a date if you want to be told.
* The first email names the days that really remain. A key whose date was set five days ahead says 5 days, not 14.
* A key made with a lifetime of 14 days or less gets only the 3 day reminder.
* A key whose creator is not recorded, which is every key made before this feature, or whose creator has left the organization, reaches the organization's admins instead.
* Each reminder is sent once per expiry value, and never for a key that is revoked or already expired.
* The email names the key by the name you gave it and carries no key, prefix or token.

## See when a key was last used

Keys and personal tokens show when they were last used and from which address. The address is the one SRE Agent resolves for the client (see [which address is judged](#which-address-is-judged)), and it is recorded at most once every five minutes per credential, so a busy key does not write on every request. A token a fix runner holds is recorded on the key that minted it.

## Allowed addresses

A key can list up to 20 IP addresses or networks, IPv4 or IPv6, such as `203.0.113.0/24`, `2001:db8::/32` or a bare address. When the list is not empty, the key is refused from any other address and from an address that cannot be determined. The refusal is the same `401` an unknown key gets, so nothing says the key exists.

* **The list governs more than the API.** It also applies to the connection of a [remote agent](https://docs.sreagent.app/guides/get-started/connect-your-data.md) and to the fix-runner tokens a key mints: a token minted from an allowed address does not work from elsewhere.
* **A key created with another key can only narrow its parent's list.** It inherits the list when it asks for none, and asking for an address outside it is refused with a `422`. Rotation carries the list.
* **`0.0.0.0/0` means every IPv4 address and no IPv6 one**, and `::/0` is the reverse. An IPv6 zone id such as `fe80::1%eth0` is refused rather than dropped.
* **Agents behind NAT or a changing egress address** need the NAT's range in the list, or no list.

### Which address is judged

The address that is compared with the list is the one SRE Agent resolves for the client, not a header the client sent. Forwarded-address headers count only when the connection comes from a proxy SRE Agent trusts, and the entry your own infrastructure appended wins over one the client added. `X-Real-IP` is ignored unless an installation turns it on, because a client can send it and a proxy may pass it through. On a self-hosted installation behind a proxy, set the trusted proxies first, or the proxy's address is what the list is compared with.

### What the list does not cover

* **Personal tokens have no list.** They belong to a person who moves between networks.
* **The handoff token a fix runner receives with a job**, used to read the brief, report and send heartbeats, is its own short-lived credential and works from any address until it ends. The list governs the key and the runner tokens minted from it, not the handoff tokens a runner is given.
* **A connected agent socket is judged when it connects and again when its key ends.** The connection stops at the key's expiry and when the key is revoked or rotated, and the agent has to authenticate again. It is not re-checked against the list on every message.

## What is recorded

| Event in Audit Logs | When |
| - | - |
| `api_key.created`, `personal_token.created` | A key or token was created. The entry carries its `expires_at` and, for a key, its allowed addresses, never the key. |
| `api_key.rotated` | A key was rotated over the REST API, with the scopes, expiry and addresses, never the secret. |
| `organization.api_key_policy_changed` | The key lifetime limit changed, with the values before and after. |

Creating a key or token in the app also asks you to [confirm it is you](https://docs.sreagent.app/guides/administer/two-step-sign-in.md#confirm-sensitive-actions), and you are emailed when one is created (see [Security alerts](https://docs.sreagent.app/guides/administer/sessions-and-security-alerts.md#security-alerts)).

## Related

* [API overview](https://docs.sreagent.app/api-reference/overview.md): scopes, personal tokens and authentication.
* [MCP tools](https://docs.sreagent.app/api-reference/mcp.md): connect a client with a key or token.
* [Two-step sign-in](https://docs.sreagent.app/guides/administer/two-step-sign-in.md): what is and is not asked for a second step.
* [Sessions and security alerts](https://docs.sreagent.app/guides/administer/sessions-and-security-alerts.md): the emails about new keys and tokens.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.