---
title: "Identity and access"
description: "Sign-in, roles, groups, service accounts, agents, approvals and the audit log for your organization, where a removed role stops working on the next request and every decision has an ID you can explain."
url: https://frazer.ai/docs/iam
index: https://frazer.ai/docs/llms.txt
tokens: 7410
---

> For agents: this page is indexed at https://frazer.ai/docs/llms.txt, and every page at https://frazer.ai/llms.txt. Copy commands from this file exactly.

# Identity and access

Identity and access decides who may do what in your organization: people, groups, service accounts and AI agents, with roles on the organization, a folder, a project or a single resource. Every API call from the console, the CLI, an MCP client or Terraform is checked the same way, at the latest version of your access rules, so a removed role stops working on the very next request. Agents can ask for changes but never approve them, and every action leaves an audit entry that says who acted and for whom.

Product overview: [Identity and access](https://frazer.ai/iam).

## How it works

One login works in many organizations: an engineer can belong to Acme and to Pellwyn with one account, and neither organization sees the other’s members. Inside an organization, resources form a tree, organization › folders › projects › resources, and a role granted on a node applies to everything below it.

Every call passes the same steps, in this order:

1.  **Authenticate**: who the principal is, the agent acting for it if any, and how strongly it signed in.
2.  **Kill switch**: the organization’s switch that suspends every agent, and suspended agents.
3.  **Token scope**: what the token allows, such as read-only.
4.  **Deny policies**: rules that refuse permissions to principals, with conditions.
5.  **Principal boundaries**, including an agent’s ceiling.
6.  **Allow**: role bindings on the resource or any parent. For an agent acting for a person, steps 4 to 6 run again for that person and both must allow.
7.  **Approval**: a rule may hold the call for a person’s approval, with a plan. This is not a denial.
8.  **Organization policy**, then **quota**.

Every IAM change increases your organization’s IAM revision in the same transaction, and every check runs at the latest revision; decisions are never cached. Every decision gets an ID, returned in the `X-Frazer-Authz-Decision` header, which you can explain later even after the rules changed.

-   **Principal**: a user, a group, a service account, an agent, or a federated identity such as a GitHub Actions job.
-   **Role**: a named set of permissions. Predefined roles are `roles/<service>.<role>`; basic roles are `roles/owner`, `roles/admin`, `roles/developer` and `roles/viewer`.
-   **Permission**: `<service>.<collection>.<verb>`, for example `kubernetes.clusters.create` or `approvals.approvals.approve`.
-   **Binding**: a role for a member on a node, with an optional CEL condition and an optional expiry.
-   **Approval**: a plan waiting for a person, pinned to the exact change and the target’s version.
-   **Decision ID**: the identifier of one allow or deny, for troubleshooting.

## Get started: give your team access

1.  Install the CLI and sign in. `frazer login` opens your browser; over SSH, `frazer login --no-browser` prints a code to confirm on another device. The CLI’s key stays in your operating system’s keychain.
    
    ```sh
    curl -fsSL frazer.ai/install | sh
    frazer login
    ```
    
2.  Invite people in **Organization › IAM › Members** with **Invite**: an email address, a role, and optionally a project. An invitation is single-use, sends a reminder on day 5 and expires after 7 days. The person accepts it with the invited address, once it is verified.
    
3.  Create a group, such as `engineering`, in **Organization › IAM › Groups and roles**, and add the people to it.
    
4.  Grant the group a role on a project.
    
    ### CLI
    
    ```sh
    frazer projects add-iam-policy-binding acme-production \
      --member group:engineering --role roles/developer --dry-run
    ```
    
    The plan lists the bindings gained and lost. Run the command again without `--dry-run` to apply it.
    
    ### Console
    
    Open **Project › Settings › IAM**, choose **Grant access**, pick the group and the role, review the plan and apply it.
    
5.  Require a second factor for everyone in **Organization › IAM › Sign-in and SSO**. The same page sets the allowed sign-in methods, the session length, token lifetimes and the default role for new members.
    
6.  Check the result:
    
    ```sh
    frazer projects get-iam-policy acme-production
    ```
    

## Built-in roles

| Role | Name | Can | Cannot |
| --- | --- | --- | --- |
| Owner | `roles/owner` | Everything in the organization, billing included | Read secret values |
| Admin | `roles/admin` | All resources, the sign-in policy and SSO; approve agent plans | Change owners; read secret values |
| Developer (default) | `roles/developer` | Create, change and delete clusters, data, network and monitoring resources; write secret values; approve agent plans in their projects | Members, roles and billing; delete protected resources |
| Responder | `roles/responder` | Read everything in scope; acknowledge and resolve incidents; silences and maintenance windows | Change resources |
| Viewer | `roles/viewer` | Read everything in scope | Any change |
| IAM admin | `roles/iam.admin` | Members, invitations, groups and roles; given with Owner to whoever creates the organization | Grant a role it does not hold |
| Billing admin | `roles/billing.admin` | Invoices, payment methods, spend caps and usage | Resources |
| Servers admin | `roles/servers.admin` | Sites, servers, pools, provider accounts and Frazer Link settings | Members, billing |
| Audit viewer | `roles/audit.viewer` | Read the audit log, IAM, sessions, tokens and policies | Any change |

Basic roles never include IAM administration, impersonating a service account, minting tokens or reading secrets; those are always granted on their own. No role reads a secret value, owners included: people write new versions with a reason and see the metadata, and workloads read the values. Reading one in an emergency is a separate, recorded two-person procedure.

New members get Developer. An Owner can make Admin the default, and production projects can stay narrower with project bindings. Every organization keeps at least one owner; removing the last one is refused.

**Predefined roles** cover each service, such as `roles/kubernetes.viewer` or `roles/dns.recordEditor`; `frazer iam roles list` lists them with their permissions. **Custom roles** are your own permission sets on an organization (`organizations/{organization}/roles/{role}`) or a project. Deleting a custom role that is in use is refused unless you force it, and the error lists the bindings.

## Sign in and step up

| Method | Notes |
| --- | --- |
| Email and password | At least 15 characters (12 on a change once a second factor is enrolled, 128 at most); checked against known breaches; no composition rules and no forced rotation |
| Google and GitHub | Linked to an existing account only after you sign in to it the usual way and confirm |
| Passkeys | Discoverable credentials with user verification; a passkey counts as two factors |
| Authenticator app | Time-based codes, plus 10 recovery codes; using one replaces the whole set |
| SSO and SCIM | Per-organization OIDC or SAML, verified domains, groups mapped to roles, SCIM deprovisioning; see [Single sign-on](#single-sign-on-and-scim) |

**Step-up.** Sensitive actions need a passkey or second factor from the last 10 minutes: creating a personal access token, changing your factors, deleting an organization, project or cluster, clearing a resource’s `protected` flag, and approving a change. In the CLI, run `frazer login --step-up` first. A personal access token never satisfies step-up, so a token can never create a token.

**Sessions and tokens.**

| Client | Lifetime |
| --- | --- |
| Console session | 7 days idle, 30 days at most; your organization can shorten it. The second-factor level lasts until 24 hours after the factor or 1 hour of inactivity, whichever comes first |
| CLI | Access tokens 15 minutes; the refresh token is bound to a key on your machine, 30 days idle, 90 days at most |
| MCP clients and apps | Access tokens 15 minutes; refresh 30 days at most |
| Personal access token | 90 days by default, 5 minutes to 365 days |
| Workload identity | 15 minutes |

**Protection.** After 5 failed sign-ins to an account, every attempt solves a proof-of-work challenge; after 10, the account is locked for 15 minutes for passwords, while passkeys and browsers the account already knows still get in. A sign-in from a new device, country or network sends you an email with a **This wasn’t me** link, which signs out every session and pauses every token. Your sessions, connected apps and agents, and personal access tokens are listed under your avatar, in **Account**, where you can revoke each one.

## Organize people with groups

Groups belong to the organization and nest up to 5 levels deep. A membership can carry an expiry, with reminders 7 days and 1 day before it ends. A membership’s source is manual, SCIM, or a claim from your identity provider; SCIM and claim memberships are changed only in the identity provider. To map an identity provider group to a role, bind the role to the group like any other member; there is no separate mapping table.

Adding a member to a group grants them the group’s roles, so it follows the same rule as any grant: you cannot grant what you do not hold yourself. Removing a member, or a nested group, takes effect on the next request.

## Restrict access with conditions and deny policies

A binding can carry a condition in CEL, evaluated on every request. Conditions read the request (`request.time`, `request.auth.aal`, `request.auth.amr`, `request.auth.auth_age`, `request.origin.ip`, `request.origin.network`), the resource (`resource.name`, `resource.type`, `resource.service`, `resource.matchTag()`, `resource.hasTagKey()`) and the principal (`principal.kind`). Conditions read tags, never labels. An error while evaluating a condition fails closed.

**Deny policies** sit on the organization, a folder or a project and win over any allow. They name denied principals and exceptions, denied permissions with wildcards such as `kubernetes.*` or `*.delete`, and a condition. Every permission can be denied.

```text title="Deny policy on the organization"
denied permissions: *.delete
condition:
  principal.kind == "agent"
    && resource.matchTag("frazer.ai/env", "production")
```

**Principal boundaries** cap what a principal can ever do, whatever it is granted; an agent’s ceiling is a boundary. A resource with `protected` set cannot be deleted by anyone until a person clears the flag with step-up.

## Run CI and workloads without keys

Service accounts live in a project. Keys are off by default through an organization policy; where you allow them, they expire within 90 days. Instead, let CI sign in with its own identity: with workload identity federation, a GitHub Actions job exchanges its OIDC token for a 15-minute Frazer token, and a condition on the token’s claims decides which jobs may.

```text title="Workload identity condition"
repository == "acme/platform-envs" && ref == "refs/heads/main"
```

Bind the role to the federated principal or principal set directly; no service-account impersonation is needed. Attaching a service account to a workload (`actAs`) and impersonating it to get a token are separate permissions, and an impersonation chain is at most 3 long. Frazer clusters use workload identity too: a cluster’s service-account token is trusted because Frazer registered the cluster’s issuer when it created the cluster.

Create a service account in **Organization › IAM › Service accounts**, with `frazer iam service-accounts create`, or as `frazer_iam_service_account` with the Frazer provider for [Terraform and OpenTofu](https://frazer.ai/docs/terraform).

## Use personal access tokens

A personal access token starts with `frz_pat_`, is bound to one organization and to scopes (`<service>:read`, `<service>:write` or `cloud-platform`), and must expire: 90 days by default, at most 365 days, and your organization can cap it or turn tokens off. Create one in **Account › Personal access tokens and CLI tokens**, or with `frazer identity personal-access-tokens create`; both need a fresh step-up. A token can carry up to 20 allowed networks, and a call from anywhere else is refused before any other check. Frazer emails you 7 days and 1 day before a token expires, and a token found in a public GitHub repository is revoked at once. Prefer workload identity for CI.

## Connect agents and MCP clients

An MCP client connects to `https://mcp.frazer.ai` with OAuth. On the consent page you pick one organization and see the client’s name and host, the scopes in words, and the refresh lifetime; read-only is on by default, and write scopes are opt-in per grant. The resulting token works only in that organization and only within your own rights.

-   A write tool does not write. It returns a plan, and an approval waits for a person; see [Approve changes](#approve-changes).
-   **Organization › IAM › Agents and MCP** lists every connected agent with its ceiling, toolsets and approval policy. **Suspend all agents** is a kill switch checked on every request, so every agent token stops working on its next call.
-   In the audit log an agent’s action names the agent, the person it acted for, the client and the approval.

## Approve changes

One approvals engine handles every plan → approve → apply in Frazer: agent writes, IAM changes made over MCP, quota increases, production changes, and other actions that need a second person.

**How a held call works.** When a rule holds a call, Frazer runs it as a plan, creates an approval, and answers `FAILED_PRECONDITION APPROVAL_REQUIRED` with the approval’s name and its page, `https://console.frazer.ai/approvals/<name>`. Nothing has changed yet. As soon as enough people approve, Frazer applies exactly that plan, once, as the person or agent that asked, after checking their permissions again.

**Who may vote.** People only, from the console or the Frazer CLI, with a passkey or second factor from the last 10 minutes. Agents, service accounts, MCP and SDK tokens, Terraform and personal access tokens can ask, never vote. The requester never counts toward a four-eyes quorum, and neither does the person an agent acted for. Any eligible rejection ends the approval.

**Two clocks.** A pending approval expires after 24 hours by default (7 days for quota requests). Once approved, the change must start within 15 minutes of the last vote. If the target changes in between, the approval is invalidated and the change is requested again.

```sh
# Approve from the terminal
frazer login --step-up
frazer approvals list --can-decide
frazer approvals approve apr_01JA3KQ7

# The requester's side: follow it until it is applied
frazer approvals wait apr_01JA3KQ7
```

**Built-in rules** cannot be turned off: any write through MCP (four eyes in production; outside production the person the agent acts for may confirm it), IAM changes through MCP (always four eyes), and quota requests above the organization’s limit or the tier ceiling.

**Your approval policy.** Each organization and each project has one approval policy; a project inherits its organization’s:

| Field | Meaning | Default |
| --- | --- | --- |
| `production` | Four eyes on every approval in the project | Off |
| `required_approvals` | Votes needed | 1, or 2 in production |
| `approvers` | People or groups admitted, narrowing who holds the approve permission | Everyone with `approvals.approvals.approve` |
| `hold_people` | Hold people’s own calls too: `DESTRUCTIVE`, `IAM` | None |
| `pending_lifetime` | How long a pending approval waits | 24 hours |
| `escalate_after`, `escalation_contacts` | When and to whom to escalate | 1 hour; the organization’s owners |

Strengthening a policy applies at once. Weakening it, for example turning off `production` or lowering `required_approvals`, is itself held for approval with four eyes. By default no direct call by a person is held, so Terraform and GitOps pipelines keep their pull-request review as the approval; opt in per project with `hold_people`.

**Records.** Every vote, decision, expiry and apply is in the audit log, and the record of the applied change names the requester and every approver. Each decided approval is also a signed record; check it with `frazer approvals verify`, against the keys from `frazer approvals attestation-keys export`.

**Just-in-time access and break-glass.** An entitlement lets named people request a role on a scope for at most 8 hours, with a justification and an approver who is never the requester and never an agent; the grant expires on its own. For an emergency, a person who holds `approvals.approvals.breakGlass` applies their own pending change at once with a justification and a hardware security key; owners are alerted immediately, and a second person must review it within 24 hours or it escalates.

## Troubleshoot a denied request

A denied call returns `PERMISSION_DENIED` from `iam.frazer.ai` with the step that refused it (`deniedBy`: kill switch, token scope, deny, boundary, allow, condition or session assurance), the permission and resource, up to three of the smallest roles that would allow it (`rolesGranting`), and a decision ID. The message ends with “(or it might not exist)” because a missing and a forbidden resource look the same.

Explain it with `frazer iam decisions troubleshoot-access`, the MCP tool `iam_troubleshoot_access`, or the console page in the error’s help link, `console.frazer.ai/iam/troubleshoot?decision=<id>`. The answer replays the decision at the revision it was made, shows the outcome now, and lists what changed in between:

-   **For yourself** you see the outcome, the step and the roles that would grant access, and a **Request access** link, with nothing that names another member or a rule.
-   **For an IAM viewer** the answer adds the deny rule or binding that decided, the group path, and who could grant the role. Where you may grant it yourself, **Grant** is offered.

Decisions are kept 90 days. Every denial and approval reason, with its fix, is in the [errors reference](https://frazer.ai/docs/errors).

## Single sign-on and SCIM

1.  Verify your domain in **Organization › IAM › Sign-in and SSO** by publishing the DNS TXT record `_frazer-verify.<domain>` it shows. The same verification lets the organization create DNS zones for the domain.
    
2.  Add an SSO connection: OIDC with the issuer, client ID and client secret, or SAML, which Frazer converts to OIDC so no XML signature code runs in the core.
    
3.  Enforce it. Sign-in is identity-first: people with an email in your domain are sent to your identity provider. They can no longer use a password for your organization, and keep their access to other organizations.
    
4.  Choose how accounts are created: just-in-time on first sign-in with groups mapped to roles, or SCIM, which is then the source of truth. SCIM deprovisioning removes the membership and revokes that organization’s sessions and tokens.
    

Keep a break-glass principal: break-glass accounts are exempt from SSO enforcement, use hardware-key MFA, and survive an outage of your identity provider.

## Access and audit

**Who can change access.** Granting roles needs the right to change a node’s IAM policy, and you can never grant a role, or add a member to a group, with permissions you do not hold yourself. IAM writes through MCP are always held for approval. A change that would leave nobody able to change the organization’s IAM policy is refused.

**Audit log.** Every action records the actor, the person an agent acted for, the client, the authentication method, the approval and the result.

| Log | Records | Kept |
| --- | --- | --- |
| `ADMIN_ACTIVITY` | Every change, always on | 400 days |
| `SYSTEM_EVENT` | Changes Frazer makes on its own, such as repairs and upgrades | 400 days |
| `DATA_ACCESS` | Secret metadata reads, kubeconfig and token mints, log queries, exports; opt-in per service | 30 days, configurable |
| `POLICY_DENIED` | Every refused call: IAM, deny, organization policy, quota, agent ceiling | 30 days |
| `STAFF_ACCESS` | Every time Frazer staff touch your data or resources, with a justification, in your own log within 1 minute | 400 days |

Every IAM change’s record carries the bindings and memberships added and removed. A write-once copy of the audit log is kept in object storage. Read it in **Organization › Settings › Audit log** or **Project › Settings › Audit log**, filtered by person, service account or agent, and export it.

## Limits and quotas

| Item | Default |
| --- | --- |
| Role bindings per resource node | 10,000 |
| Role bindings per organization | 1,000,000 |
| Group nesting depth | 5 |
| Groups per organization | 10,000 |
| Direct members per group | 100,000 |
| Groups a principal belongs to, transitively | 1,000 |
| Condition size | 2 KB, estimated cost 1,000 |
| Conditional bindings with the same role and principal on one node | 20 |
| Deny rules per node | 500 |
| Boundaries per principal set | 10 |
| Custom roles per organization; permissions per custom role | 1,000; 3,000 |
| IAM writes per organization | 20 per second sustained |
| Organizations you create | 3 per 24 hours; 10 owned |
| Open invitations per organization | 50 |
| Invitations sent per day | 20 for organizations younger than 7 days, then 100 |
| Personal access tokens created per user | 20 a day |
| Pending approvals per requester | 50 |
| Plan size held for approval | 256 KiB |

The IAM limits are soft limits per organization: a write that would pass one is refused, and the error names the limit.

## Pricing

Identity and access has no line of its own on the price list. Every line, with the estimator:

| Identity and access | On your servers | On the Frazer fleet |
| --- | --- | --- |
| Price | **Included**: SSO (OIDC, SAML), SCIM, MFA, roles and audit logs | **Included** in every organization |

Every line, with the estimator: [pricing](https://frazer.ai/pricing#lines).

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| `PERMISSION_DENIED` right after someone granted you a role | The grant went to another project, folder or principal, or a deny policy or boundary still refuses it | Explain the decision ID; the replay shows which step refused |
| `STEP_UP_REQUIRED` in the CLI | Your last second factor is older than 10 minutes, or you used a personal access token | Run `frazer login --step-up` and retry |
| An MCP client lists no write tools | The grant is read-only, or the token is for another organization | Reconnect the client and turn on write scopes for this organization |
| An agent’s change returns `APPROVAL_REQUIRED` | Writes through MCP are held for a person | Approve it on the approval page or with `frazer approvals approve` |
| You cannot approve your own agent’s production change | Production needs four eyes; the person an agent acts for does not count | Ask another approver |
| An approval failed with `PLAN_CHANGED` | The target changed after the plan was made | Request the change again |
| You cannot remove someone from a group | The membership comes from SCIM or your identity provider | Remove them in the identity provider |
| A new member cannot accept an invitation | The invitation expired after 7 days, or their address is not verified or does not match | Resend the invitation, or have them verify the invited address |
| Someone you removed still appears in a project | They hold a role there through another group or a direct binding | Check the project’s policy with `frazer projects get-iam-policy` |

> **Tip:**
> 
> Every CLI error for a denial prints its decision ID. Keep it: it is all you need to explain the denial later.

## Reference

### CLI

| Command | What it does |
| --- | --- |
| `frazer login` | Sign the CLI in through your browser; with --no-browser, confirm a code on another device instead. |
| `frazer login --step-up` | Confirm with a passkey or second factor, good for 10 minutes, before you approve or create a token. |
| `frazer logout` | Revoke the CLI's grant and delete its key. |
| `frazer auth print-access-token` | Print an access token for the active configuration. |
| `frazer auth list` | List the CLI's configurations and their grants. |
| `frazer identity personal-access-tokens create` | Create a personal access token; needs a fresh step-up. |
| `frazer projects get-iam-policy` | Show a project's role bindings. |
| `frazer projects add-iam-policy-binding` | Grant a role to a member on a project. |
| `frazer projects remove-iam-policy-binding` | Remove a member's role on a project. |
| `frazer iam groups create` | Create a group in the organization. |
| `frazer iam memberships create` | Add a person, a service account or a group to a group. |
| `frazer iam service-accounts create` | Create a service account in a project. |
| `frazer iam roles list` | List predefined and custom roles with their permissions. |
| `frazer iam decisions troubleshoot-access` | Explain a decision by its ID, or a principal's access to a resource. |
| `frazer approvals list` | List approvals; with --can-decide, only the ones you may decide. |
| `frazer approvals get` | Show an approval with its plan, votes and state. |
| `frazer approvals approve` | Vote to approve; needs a fresh step-up. |
| `frazer approvals reject` | Reject with a reason; one rejection ends the approval. |
| `frazer approvals cancel` | Cancel an approval you requested. |
| `frazer approvals wait` | Follow an approval until it is applied or ends. |
| `frazer approvals verify` | Check a decided approval's signed record. |
| `frazer approvals attestation-keys export` | Export the public keys that sign approval records. |

All of them: [CLI reference](https://frazer.ai/docs/cli).

### Terraform and OpenTofu

| Resource | What it manages |
| --- | --- |
| `frazer_iam_service_account` | A service account in a project. |

All of them: [Terraform and OpenTofu reference](https://frazer.ai/docs/terraform).

### MCP tools

| Tool | What it does |
| --- | --- |
| `iam_troubleshoot_access` | Explain a decision by its ID, or a principal's access to a resource. |
| `approvals_list` | List approvals, such as the ones an agent's writes are waiting on. |
| `approvals_get` | Get an approval and, once applied, the result of the change. |
| `approvals_begin_batch` | Start a batch, so up to 100 held writes become one approval. |
| `approvals_submit_batch` | Submit a batch of held writes for one approval. |

All of them: [MCP tools reference](https://frazer.ai/docs/mcp).

### Events

| Event type | When it is sent |
| --- | --- |
| `frazer.member.added.v1` | A person joined the organization or a project. |
| `frazer.member.removed.v1` | A person was removed from the organization or a project. |

All of them: [Events reference](https://frazer.ai/docs/webhooks).

### Errors

| Reason | What it means | How to fix it |
| --- | --- | --- |
| `LAST_IAM_ADMIN` | The change would leave the organization with nobody who can change its IAM policy. | Grant the role to another person first. |
| `GROUP_CYCLE` | The group would contain itself through its members. | Remove the nesting that closes the loop. |
| `GROUP_DEPTH_EXCEEDED` | Groups would nest more than 5 levels deep. | Flatten the group tree. |
| `MEMBERSHIP_MANAGED_EXTERNALLY` | The membership comes from your identity provider through SCIM or a sign-in claim. | Change it in your identity provider. |
| `ETAG_REQUIRED` | A full policy replace was sent without the policy's etag. | Read the policy, edit it and send it back with its etag, or add and remove single bindings instead. |
| `LIMIT_EXCEEDED` | An IAM limit, such as bindings per resource, would be passed. | Use groups instead of many direct bindings, or ask for the limit to be raised. |
| `APPROVER_NOT_ALLOWED` | Only people can vote, and the approval's approvers must include you. | Ask an eligible approver; agents, service accounts and tokens never vote. |
| `APPROVER_CLIENT_NOT_ALLOWED` | Votes come only from the console or the Frazer CLI. | Vote in the console or with frazer approvals approve. |
| `SELF_APPROVAL` | You requested the change, or an agent asked for you, and the rule needs another person. | Ask a colleague who is an approver. |
| `APPLY_DEADLINE_EXCEEDED` | The approved change did not start within 15 minutes of the last vote. | Request the change again. |
| `PLAN_TOO_LARGE` | Plans over 256 KiB are not held for approval. | Split the change into smaller ones. |
| `BREAK_GLASS_NOT_ALLOWED` | Break-glass is only for a change you asked for directly, not through MCP, an agent or a workload. | Make the request yourself from the console or the CLI. |
| `HARDWARE_KEY_REQUIRED` | Break-glass needs a step-up with a hardware security key. | Step up with a device-bound security key. |

All of them: [Errors reference](https://frazer.ai/docs/errors).

## Related

-   [Identity and access product page](https://frazer.ai/iam)
-   [Security Center](https://frazer.ai/docs/security-center): identity risks, unused permissions and just-in-time access findings
-   [Billing and budgets](https://frazer.ai/docs/billing): billing roles and accounts
-   [Secrets](https://frazer.ai/docs/secrets): write-only values and audited access
-   [MCP reference](https://frazer.ai/docs/mcp): tools, scopes and consent
-   [Errors reference](https://frazer.ai/docs/errors)

## Pages in Operate and secure

- [Frazer Monitoring](https://frazer.ai/docs/monitoring.md)
- [Security Center](https://frazer.ai/docs/security-center.md)
- [Identity and access](https://frazer.ai/docs/iam.md) (this page)
- [Overview](https://frazer.ai/docs/billing.md)
