# Least privilege for provider admin and usage keys

URL: https://infro.io/blog/provider-admin-key-least-privilege
Author: INFRO Editorial (https://infro.io/blog/editorial)
Publisher: INFRO
Published: 2026-09-29
Last modified: 2026-09-29
Last reviewed: 2026-09-29 (next review due 2026-10-29)
Topic: Security and governance
Format: Guide

> Keep inference and administration on separate credentials, give each integration its own key, set expiries, and store admin keys in one place used by one consumer. OpenAI admin keys work only on administration endpoints; an Anthropic Claude Console admin key carries full access to every endpoint that accepts admin keys; Bedrock permissions follow IAM. Where a key cannot be narrowed, narrow who holds it and watch the provider's audit log.

Key takeaways:
- An inference key spends money; an admin key can change who may spend it. Never let one credential do both.
- OpenAI admin keys cannot call model endpoints; an Anthropic Console admin key has no selectable scopes.
- On Bedrock, short-term API keys last up to 12 hours and AWS recommends long-term keys only for exploration.
- Where a key cannot be narrowed, narrow who holds it, how long it lives and how many systems use it.
- Read the provider's own audit log for anything an admin key wrote when it should only have read.

Most guidance about AI API keys is about the key that calls the model: keep it server-side, give each service its own, set a spend limit. That key is dangerous because it spends money. There is a second kind of provider credential that gets far less attention and can do more damage: the admin key an organization creates so that a finance tool, a FinOps platform or a gateway can read its usage and cost reports.

At most providers, the credential that can read a cost report is an administrative credential. What else it can do varies a great deal, and the variation decides how carefully it has to be held.

## Two credentials, two blast radii

An inference key's worst case is spend: whoever holds it can run requests on the account until a limit, a quota or someone's attention stops them. It usually cannot see who else is in the organization or change anything about it.

An admin key's worst case is control. Depending on the provider it may invite users, change roles, deactivate keys, alter spend limits or change data-retention settings. A leaked admin key can therefore do something a leaked inference key cannot: make the next incident harder to detect and harder to contain.

[Diagram: What a leaked key can do, by credential type, as each provider documents it on 2026-09-29.]

The first rule follows directly: never use one credential for both jobs. Most providers make this easy by design; the risk is an integration that asks for the more powerful key "to be safe".

## What each provider lets you scope

**OpenAI.** Admin APIs cover organization management: user invitations, audit log review, project administration, API key management, spend limits and alerts, data retention and rate limits, all through an Admin API key[1]. The guide states that admin keys cannot be used for non-administration endpoints[1], so an admin key cannot run model requests. It does not describe a read-only admin key. For ordinary keys, OpenAI recommends setting an expiration when creating a project API key and establishing a regular rotation process, and describes organization-level governance that can restrict which types of API key may be created[2]. Its permissions guide advises starting from the minimum permissions a task needs and adding only as needed[3].

**Anthropic.** On a Claude Console organization, only members with the admin role can create an Admin API key, and the creator chooses an expiration when the key is made[4]. The same page is explicit about scope: Console keys do not have selectable scopes, and every key carries full access to all endpoints that accept Admin API keys[4]. That includes the Usage and Cost API, which requires an admin credential; workspace API keys do not work for it[5]. One useful limit: the Admin API cannot create new API keys — it can read, rename and change the status of existing ones[6]. Claude Enterprise organizations are different: their keys are created in claude.ai with scopes selected at creation, including a read-only `read:org_audit` scope for security-audit integrations[4].

**AWS Bedrock.** Bedrock has no separate admin key; permissions follow IAM. Bedrock API keys come in two kinds: short-term keys last up to 12 hours and inherit the permissions of the IAM principal that generated them, while long-term keys last until a configured expiration and create an IAM user with attached policies[7]. AWS labels long-term keys as recommended only for exploration, and documents IAM condition keys to cap their age and to allow or deny calls made with a bearer token[7].

[Diagram: Admin and usage credentials compared from each provider's documentation. "Not described" means the page read did not say, not that the capability is absent.]

## Hold the key you cannot narrow

When a provider offers scopes, use the narrowest that works. When it does not — the Anthropic Console admin key is the clearest case — the least-privilege work moves from the key to everything around it:

- **Who creates it.** An admin who expects to stay in the role, with the key named after the one integration that uses it.
- **How long it lives.** The shortest expiry the integration tolerates, with the date in a calendar and an owner for the renewal.
- **Where it is stored.** One secret manager entry or one integration that seals it. Never a ticket, a chat message or a shared document.
- **How many systems use it.** One. Two tools sharing an admin key means revoking it breaks both, which is exactly the pressure that keeps a compromised key alive.
- **What it is watched by.** The provider's own audit log. A reporting integration's key that ever changes a role or a limit is an incident.

[Diagram: The lifecycle of an admin credential. The steps are the same whether or not the provider offers scopes; scopes only make the first step smaller.]

An admin key can also audit the other keys. This script uses an Anthropic admin key to list active API keys and flag any with no expiry or an expiry in the next two weeks, using the Admin API's key listing, which returns each key's `expires_at`[6]:

```python
import os
from datetime import datetime, timedelta, timezone

import anthropic

# Read the admin key from the environment your secret manager populates.
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_ADMIN_KEY"])

soon = datetime.now(timezone.utc) + timedelta(days=14)
findings = []

# The SDK's list method pages automatically.
for key in client.beta.organization.api_keys.list(status="active"):
    if key.expires_at is None:
        findings.append((key.id, key.name, "no expiry"))
    elif key.expires_at <= soon:
        findings.append((key.id, key.name, f"expires {key.expires_at:%Y-%m-%d}"))

for key_id, name, reason in findings:
    print(f"{key_id}\t{name}\t{reason}")
```

On Bedrock, the equivalent guard is an IAM policy on the identities that create long-term keys. AWS documents this example, which allows creating Bedrock keys only with an age of 90 days or less[7]:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iam:CreateServiceSpecificCredential",
      "Resource": "*",
      "Condition": {
        "NumericLessThanEquals": { "iam:ServiceSpecificCredentialAgeDays": "90" },
        "StringEquals": { "iam:ServiceSpecificCredentialServiceName": "bedrock.amazonaws.com" }
      }
    }
  ]
}
```

## When a vendor asks for an admin key

Cost reconciliation, FinOps platforms and AI gateways all ask for admin credentials, because provider cost data sits behind them. Before handing one over, ask:

- [ ] Which endpoints will you call, and are they all read endpoints?
- [ ] Is the admin key kept separate from any inference key you hold for us?
- [ ] How is it stored, and can anyone — including your staff — display it again?
- [ ] Will you tell us when the key is rejected, revoked or close to its provider-reported expiry?
- [ ] Can we remove it without breaking inference traffic?

If the vendor needs only reports, the right answer to every write question is that it never makes one. The provider's audit log is how you check.

## What INFRO asks for, and why

INFRO keeps the two jobs on two credentials, as its [reconciliation](https://infro.io/docs/cost/reconciliation) and [billing](https://infro.io/docs/org/billing) documentation describes:

- **The inference credential** is attached to a provider connection and used to send requests and read the usage the provider reports back — never to read the account or its billing. It is sealed with AES-256-GCM, bound to the organization and connection, and never shown again; see [Connect a provider](https://infro.io/docs/providers).
- **The billing credential** is optional, connected separately under Reconciliation, and used to read the provider's cost reports once a day and compare them with INFRO's estimates. It is an OpenAI Admin key or an Anthropic `sk-ant-admin` key. It is sealed under its own binding, never shown again, and INFRO uses documented read-only endpoints with it: costs, and where supported, usage, organization, key-lifecycle and rate-limit metadata. INFRO alerts the organization's billing contact when it is rejected, revoked, expired or near a provider-reported expiry. Reconciliation is on the Business plan.
- The billing credential is not managed through the management API or Terraform; it is set in the console only, and connecting, removing it and changing its usage access are written to the [audit log](https://infro.io/docs/org/audit-log).

Two consequences are worth stating plainly. First, INFRO reading only is a property of INFRO's code, not of the key: an Anthropic Console admin key carries full admin access at Anthropic whoever holds it, so apply the holding rules above — a dedicated key, a short expiry, and Anthropic's audit trail — to the one you connect. Second, a Bedrock connection in INFRO holds a Bedrock API key. A short-term key expires within 12 hours, so a connection meant to serve for longer needs a long-term key, which AWS recommends only for exploration; if you use one, attach the narrowest IAM policy the models you route require, cap its age, and rotate it on a schedule.

## Sources

1. Admin APIs — OpenAI. https://developers.openai.com/api/docs/guides/admin-apis (accessed 2026-09-29)
2. Production best practices — OpenAI. https://developers.openai.com/api/docs/guides/production-best-practices (accessed 2026-09-29)
3. Manage permissions in the OpenAI platform — OpenAI. https://developers.openai.com/api/docs/guides/rbac (accessed 2026-09-29)
4. Create an Admin API key — Anthropic. https://platform.claude.com/docs/en/manage-claude/admin-api-keys (accessed 2026-09-29)
5. Usage and Cost API — Anthropic. https://platform.claude.com/docs/en/manage-claude/usage-cost-api (accessed 2026-09-29)
6. Admin API — Anthropic. https://platform.claude.com/docs/en/manage-claude/admin-api (accessed 2026-09-29)
7. API keys — Amazon Bedrock User Guide — Amazon Web Services. https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html (accessed 2026-09-29)
