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

# Access Control

> Configure roles, API tokens, multi-factor authentication, and LDAP / Active Directory authentication realms for Ironcore Backup Solution.

## Overview

Ironcore Backup Solution (IBS) is **restricted by default** — newly created
users and API tokens have no permissions until an administrator grants them.
Access is governed by a role-based access control (RBAC) model with per-datastore
and per-namespace permissions, supported by multiple authentication realms,
multi-factor authentication, and revocable API tokens for automation.

This page covers the full access control surface.

<Note>
  **Prerequisites**

  * Administrator role on the Polystack platform
  * For LDAP / Active Directory integration: a service account and connection
    details for the directory
</Note>

***

## Authentication Realms

| Realm                     | Use Case                                  | Notes                                            |
| ------------------------- | ----------------------------------------- | ------------------------------------------------ |
| **Built-in**              | Local users, system-independent           | Default realm for service accounts and operators |
| **Linux PAM**             | Operating system users on the backup host | Useful for tightly-controlled admin access       |
| **LDAP**                  | Centrally-managed directory               | Includes group sync                              |
| **Active Directory**      | Microsoft AD integration                  | Includes group sync and SSO via Kerberos         |
| **OpenID Connect (OIDC)** | Single sign-on to a central IdP           | Most common modern federation                    |

### Configure LDAP

<Tabs>
  <Tab title="Deployment Console" icon="gauge">
    <Steps titleSize="h3">
      <Step title="Open Realms" icon="external-link">
        Navigate to **Backup Solution** > **Access Control** > **Realms**.
      </Step>

      <Step title="Add an LDAP realm" icon="plus">
        Click **Add** > **LDAP**. Enter:

        * **Realm name**: `corporate-ldap`
        * **Server**: `ldap://ldap.<your-domain>`
        * **Base DN**: `dc=polystack,dc=local`
        * **User attribute**: `uid`
        * **Bind DN**: `cn=ibs-svc,ou=services,dc=polystack,dc=local`
        * **Bind password**: (service account password)
      </Step>

      <Step title="Enable group sync" icon="users">
        Set:

        * **Group base DN**: `ou=groups,dc=polystack,dc=local`
        * **Group filter**: `(objectClass=groupOfNames)`
        * **Sync schedule**: `daily 06:00`
      </Step>

      <Step title="Test" icon="signal">
        Click **Test**. The Dashboard performs a probe bind and reports success.
      </Step>

      <Step title="Save" icon="check">
        Click **Save**.

        <Check>LDAP users can now log in. Group membership populates the `@corporate-ldap` realm.</Check>
      </Step>
    </Steps>
  </Tab>

  <Tab title="CLI" icon="terminal">
    ```bash title="Create an LDAP realm" theme={null}
    ironcore-backup realm create \
      --type ldap \
      --realm corporate-ldap \
      --server "ldap://ldap.<your-domain>" \
      --base-dn "dc=polystack,dc=local" \
      --user-attr uid \
      --bind-dn "cn=ibs-svc,ou=services,dc=polystack,dc=local" \
      --bind-password-file /etc/ironcore/ldap-svc-password
    ```
  </Tab>
</Tabs>

### Configure Active Directory

<Tabs>
  <Tab title="Deployment Console" icon="gauge">
    Navigate to **Realms** > **Add** > **Active Directory**. Most fields
    mirror LDAP. The key differences:

    | Field               | Active Directory Value    |
    | ------------------- | ------------------------- |
    | **Server**          | `ldap://ad.<your-domain>` |
    | **User attribute**  | `sAMAccountName`          |
    | **Default domain**  | `<your-domain>`           |
    | **Group attribute** | `memberOf`                |
  </Tab>

  <Tab title="CLI" icon="terminal">
    ```bash theme={null}
    ironcore-backup realm create \
      --type ad \
      --realm corp-ad \
      --server "ldap://ad.<your-domain>" \
      --default-domain "<your-domain>" \
      --bind-dn "CN=ibs-svc,OU=services,DC=corp,DC=local" \
      --bind-password-file /etc/ironcore/ad-svc-password
    ```
  </Tab>
</Tabs>

### Configure OpenID Connect

For federated SSO to your central IdP:

```bash title="OIDC realm" theme={null}
ironcore-backup realm create \
  --type openid \
  --realm corporate-sso \
  --issuer-url https://sso.<your-domain>/realms/corporate \
  --client-id ironcore-backup \
  --client-key /etc/ironcore/oidc-client-key.pem \
  --default-roles "Datastore.Reader@/datastore/ibs-primary/production"
```

***

## Roles

IBS ships with a set of built-in roles. Each role is a named collection of
privileges. Compose roles for the principle of least privilege.

| Role                  | Typical Use            | Key Privileges                                        |
| --------------------- | ---------------------- | ----------------------------------------------------- |
| **Admin**             | Platform administrator | All privileges on all paths                           |
| **Audit**             | Read-only auditor      | View configuration and audit logs                     |
| **Datastore.Admin**   | Datastore owner        | Manage datastores, namespaces, backups                |
| **Datastore.Backup**  | Project member         | Create backups in a specific datastore                |
| **Datastore.Reader**  | Read-only              | List and restore from a datastore                     |
| **Datastore.Powered** | Power operator         | Backup + Restore + Prune (no datastore admin)         |
| **Datastore.Audit**   | Datastore auditor      | View snapshots and audit trail; no read of chunk data |
| **Tape.Admin**        | Tape operator          | Manage media pools, tape jobs                         |
| **Sys.Audit**         | System auditor         | Read system configuration                             |

### Grant a Role

Permissions are granted by combining (auth-id, role, path).

| Component   | Description                                            |
| ----------- | ------------------------------------------------------ |
| **Auth-id** | `user@realm` or `user@realm!token-name` for API tokens |
| **Role**    | A built-in or custom role                              |
| **Path**    | The scope — datastore, namespace, or `/` for global    |

<Tabs>
  <Tab title="Deployment Console" icon="gauge">
    Open **Access Control** > **Permissions** > **Add**. Pick the user
    or token, the role, and the path.
  </Tab>

  <Tab title="CLI" icon="terminal">
    ```bash title="Grant Datastore.Backup on a namespace" theme={null}
    ironcore-backup acl update \
      --path /datastore/ibs-primary/production \
      --auth-id alice@polystack \
      --role Datastore.Backup
    ```

    ```bash title="Grant Datastore.Reader to a group from LDAP" theme={null}
    ironcore-backup acl update \
      --path /datastore/ibs-primary \
      --auth-id @audit-team@corporate-ldap \
      --role Datastore.Reader
    ```
  </Tab>
</Tabs>

### Custom Roles

Compose roles for unusual access patterns:

```bash title="Create a backup-only-no-restore role" theme={null}
ironcore-backup role create \
  --name BackupOnlyNoRestore \
  --privileges "Datastore.Backup,Datastore.AuditAudit-Log,Datastore.Audit"
```

***

## API Tokens

API tokens are scoped, revocable credentials for automation. Each token has a
unique secret that is shown **only once** at creation.

<Tabs>
  <Tab title="Deployment Console" icon="gauge">
    <Steps titleSize="h3">
      <Step title="Open API Tokens" icon="key">
        Open **Access Control** > **API Tokens** > **Add**.
      </Step>

      <Step title="Choose token details" icon="settings">
        Set:

        * **Owner**: the user the token acts as
        * **Token name**: `backup-job` (the token ID becomes `user@realm!backup-job`)
        * **Expiry**: optional date or never
        * **Privilege separation**: enable — token receives no roles automatically
      </Step>

      <Step title="Copy the secret" icon="copy">
        Copy the secret. It is shown only once.

        <Warning>The secret cannot be recovered after the dialog closes. Store it in a vault.</Warning>
      </Step>

      <Step title="Grant scoped roles" icon="lock">
        Use **Permissions** to grant only the roles the token needs — for example,
        `Datastore.Backup` on one namespace and nothing else.
      </Step>
    </Steps>
  </Tab>

  <Tab title="CLI" icon="terminal">
    ```bash title="Create an API token" theme={null}
    ironcore-backup user token create \
      --user alice@polystack \
      --name backup-job \
      --privsep
    ```

    ```bash title="Grant a scoped role" theme={null}
    ironcore-backup acl update \
      --path /datastore/ibs-primary/production \
      --auth-id "alice@polystack!backup-job" \
      --role Datastore.Backup
    ```

    ```bash title="Revoke the token" theme={null}
    ironcore-backup user token delete \
      --user alice@polystack \
      --name backup-job
    ```
  </Tab>
</Tabs>

<Tip>
  Use one API token per automation entry point (backup runner, monitoring
  exporter, sync orchestrator). Compromise of one does not require rotating
  the entire automation fleet.
</Tip>

***

## Multi-Factor Authentication

Multi-factor authentication (MFA) applies to interactive logins. API tokens are
not subject to MFA but should be tightly scoped.

| Method                        | When to Use                                              |
| ----------------------------- | -------------------------------------------------------- |
| **TOTP**                      | Time-based one-time passwords with any authenticator app |
| **WebAuthn**                  | Hardware security keys (YubiKey, Titan, etc.)            |
| **Single-use recovery codes** | Backup access in case the primary factor is lost         |

<Tabs>
  <Tab title="Deployment Console" icon="gauge">
    <Steps titleSize="h3">
      <Step title="Open My Account" icon="user">
        Click your username > **Account Settings** > **TFA**.
      </Step>

      <Step title="Add a factor" icon="plus">
        Click **Add Factor**. Choose TOTP or WebAuthn.
      </Step>

      <Step title="Save recovery codes" icon="qr-code">
        Save the recovery codes in a secure location. Each code is single-use.
      </Step>
    </Steps>
  </Tab>

  <Tab title="CLI" icon="terminal">
    ```bash title="Add a TOTP factor" theme={null}
    ironcore-backup user tfa add --type totp
    ```
  </Tab>
</Tabs>

### Enforce MFA Platform-Wide

<Tabs>
  <Tab title="Deployment Console" icon="gauge">
    Open **Access Control** > **TFA Policy**. Set **Required** to enforce
    MFA for every realm except API token logins.
  </Tab>

  <Tab title="CLI" icon="terminal">
    ```bash theme={null}
    ironcore-backup tfa policy set --require all-interactive
    ```
  </Tab>
</Tabs>

### Lockout Protection

IBS protects against brute-force attacks on MFA:

| Setting                        | Default    | Behaviour           |
| ------------------------------ | ---------- | ------------------- |
| Failed attempts before lockout | 8          | Per user            |
| Lockout duration               | 15 minutes | Auto-expires        |
| TFA reset by admin             | Permitted  | Requires Admin role |

***

## Audit Log

Every authentication, configuration change, and access grant is recorded in the
audit log.

| Source           | Captured                         |
| ---------------- | -------------------------------- |
| Realm config     | Create, update, delete           |
| User config      | Add, modify, remove, MFA changes |
| Token config     | Create, delete, scope change     |
| Role config      | Create, update, delete           |
| Permission grant | Add, remove                      |
| Failed logins    | Username, source IP, timestamp   |

<Tabs>
  <Tab title="Deployment Console" icon="gauge">
    Open **Access Control** > **Audit Log**. Filter by user, action type,
    or time range. Export as CSV for compliance reviews.
  </Tab>

  <Tab title="CLI" icon="terminal">
    ```bash theme={null}
    ironcore-backup audit log --since "30d ago" --action permission
    ```
  </Tab>
</Tabs>

***

## Recommended Permission Model

The pattern below scales to typical production deployments.

| Role Grant         | Audience          | Path                          |
| ------------------ | ----------------- | ----------------------------- |
| `Admin`            | Platform admins   | `/`                           |
| `Sys.Audit`        | Audit team        | `/`                           |
| `Datastore.Admin`  | Datastore owner   | `/datastore/<ds>`             |
| `Datastore.Backup` | Project members   | `/datastore/<ds>/<namespace>` |
| `Datastore.Reader` | Read-only viewers | `/datastore/<ds>/<namespace>` |
| `Tape.Admin`       | Tape operator     | `/system/tape`                |

<Warning>
  Do not grant the global `Admin` role to API tokens used by jobs. Always
  scope tokens to the smallest required path.
</Warning>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="`permission denied` on a path the user should have access to" icon="lock">
    Check the effective permissions:

    ```bash theme={null}
    ironcore-backup acl show --path /datastore/ibs-primary/production
    ```

    Then check the user's roles:

    ```bash theme={null}
    ironcore-backup user effective alice@polystack
    ```
  </Accordion>

  <Accordion title="LDAP group sync missing users" icon="users">
    Confirm the LDAP filter matches the expected group and that the sync
    schedule has run. Re-run a sync manually:

    ```bash theme={null}
    ironcore-backup realm sync corporate-ldap
    ```
  </Accordion>

  <Accordion title="TFA lockout for legitimate user" icon="alert-triangle">
    Admin can unlock a user:

    ```bash theme={null}
    ironcore-backup user tfa unlock alice@polystack
    ```
  </Accordion>

  <Accordion title="API token returns `unauthorized`" icon="key">
    The token may be deleted, expired, or scoped wrongly. Check:

    ```bash theme={null}
    ironcore-backup user token list --user alice@polystack
    ironcore-backup acl show --auth-id "alice@polystack!backup-job"
    ```
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Security and Encryption" icon="lock" href="/services/ironcore-backup/admin-guide/security-encryption" color="#bf9667">
    Client-side encryption, ransomware protection, master keys
  </Card>

  <Card title="Notifications" icon="bell" href="/services/ironcore-backup/admin-guide/notifications" color="#bf9667">
    Alert routing for failed logins and configuration changes
  </Card>

  <Card title="Audit Log" icon="clipboard-check" href="/services/ironcore-backup/admin-guide/access-control" color="#bf9667">
    Audit trail of access and configuration events
  </Card>

  <Card title="Datastores" icon="database" href="/services/ironcore-backup/admin-guide/datastores" color="#bf9667">
    Per-datastore and per-namespace permissions
  </Card>
</CardGroup>
