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

# Backups and Restore Points

> Register an S3-compatible bucket as a backup vault, protect a stack on a schedule, take and inspect restore points, restore a stack in place, and follow the runs that move the data.

> [!NOTE]
>
> A **backup vault** is an object-storage bucket your organisation owns that Ankra writes cluster backups to, and a **restore point** is one immutable copy of a stack's data inside it. Register a vault once, protect a stack, and every backup, restore and clone is a verb over the restore points that land there.

## Why a vault first

Ankra's answer to "copy this database to another cluster" is the industry one: take a backup, then restore it on the target. That keeps data off the platform entirely - the source cluster writes to the bucket, the target reads from it over HTTPS - and it means a disaster-recovery copy exists as a side effect of every clone.

That only works with somewhere to write to, which is what a vault is. Registering one is a one-time, organisation-level step.

> [!NOTE]
>
> **Pipelines are the exception, and they do not wait for this.** A pipeline step's log, a `scan` stage's reports and every declared artifact are kept in an Ankra-managed default vault for an organisation that has no ready vault of its own, under a key prefix of that organisation, so a first [Ankra Pipelines](https://docs.ankra.ai/guides/ankra-pipelines.md#before-your-first-run) run works before anybody registers a bucket. Backups, restore points, cloning a stack with its data and `ankra migrate` data never use it - those are organisation-scoped and are what a vault of your own is for. Register one and it takes precedence for pipeline artifacts too, from the next step onward; objects already written stay where they are.

## What a vault records

| Field | What it is |
| - | - |
| Name | How the vault is referred to in policies and the CLI |
| Provider | The object-storage service, or `other` for any S3-compatible endpoint |
| Endpoint | The S3 endpoint URL |
| Bucket | The bucket backups are written to |
| Region | Only needed when the endpoint does not imply it |
| Path style | `https://endpoint/bucket` addressing - required by most self-hosted S3 services |
| Status | `ready`, `error` (with the failure excerpt), or `provisioning` while Ankra is still creating the bucket or checking the keys |
| Kind | `ankra_provisioned` when Ankra created the bucket from one of your provider credentials, `customer_s3` when you registered a bucket you already had |

The access key ID and secret you provide are written to Ankra's secret store and never returned by the API, the dashboard, or the CLI. Rotating keys means creating a new vault or re-verifying after updating the bucket policy.

## Let Ankra create the bucket

The quickest path: pick one of your organisation's provider credentials and a region, and Ankra creates the bucket, mints or stores the access keys, verifies the bucket and registers the vault. The vault shows **Provisioning** until that has finished, then **Ready** - or **Failed** with the excerpt of what the provider refused.

| Credential | What Ankra does with it | What you still supply |
| - | - | - |
| UpCloud | Creates a Managed Object Storage service in the region, a user with the `ECSS3FullAccess` policy and an access key, then the bucket | Nothing - the region is checked against your account's list |
| DigitalOcean | Mints a Spaces access key with the API token and creates the Space | Nothing |
| Scaleway | Uses the credential's own IAM key pair (Scaleway API keys are S3 keys) and creates the bucket in the credential's project | Nothing |
| Hetzner | Creates the bucket at the chosen location with the Object Storage key pair you provide | The key pair: Hetzner issues it in the Cloud Console (**Object Storage > Manage credentials**), and its Cloud API cannot mint one - so neither can Ankra |

Other credential kinds (OVH, AWS, GCP, Azure, Proxmox, Morpheus) cannot provision a bucket yet - register a bucket you own instead, below.

**Dashboard**

**1. Open Backups**

Go to your organisation's **Settings** and choose **Backups**, then **Add vault** and **Let Ankra create the bucket**.

**2. Press the button**

The dialog opens ready: a credential Ankra can complete on its own is already selected, the vault is named for you, and the region is that provider's usual one. It says what it is about to do - "Ankra will create a bucket in europe-1 on UpCloud Object Storage and register it as 'backups'." - so pressing **Create bucket and vault** is the whole flow.

**3. Hetzner: paste the Object Storage keys**

A Hetzner credential is the one that cannot be a single click, and the picker labels it **(needs keys)**: the form asks for the access key and secret key from the Cloud Console. They are stored in Ankra's secret store and never shown again.

**4. Only if you want to change something**

**Advanced** opens the name, region and bucket for editing. Everything there already has a value; you never have to touch it.

**5. Watch it come up**

The row shows **Provisioning** with "Creating the bucket on ..."; the page refreshes on its own until it reads **Ready**. A **Failed** vault shows what the provider answered - a region your account cannot use, a bucket name someone else holds, a token without the right scope - and can be deleted and re-added once that is fixed.

**CLI**

```bash theme={null}
ankra backup vaults provision
```

That is the whole command. The vault is named `backups` (then `backups-2` and so on), the credential is the only one Ankra can provision from, and the region is that provider's usual one - and the command prints all three before it creates anything. If the organisation has several usable credentials it asks which, naming them.

Every default is an override, not a prerequisite:

```bash theme={null}
ankra backup vaults provision offsite --credential upcloud-main --region europe-1 --bucket my-backups --wait
```

`--credential` takes a credential name or id. `--wait` blocks until the vault is `ready` (or exits non-zero with the failure excerpt); without it the command returns as soon as the platform has accepted the request, and `ankra backup vaults get offsite` shows progress.

For a Hetzner credential the command prompts for the Object Storage access key and (hidden) secret key when they are not passed with `--access-key-id` / `--secret-access-key`.

> [!NOTE]
>
> Ankra records the provider-side handle it created (the UpCloud service, the DigitalOcean key) on the vault, so it can clean them up later if you ask it to - see [Deleting a vault](#deleting-a-vault).

## Bring your own bucket

**Dashboard**

**1. Open Backups**

Go to your organisation's **Settings** and choose **Backups**.

**2. Add a vault**

Click **Add vault** and pick the provider first: the dialog fills in the endpoint and region shapes that provider uses, sets **Path-style addressing** to what it expects (off for Amazon S3, on everywhere else), and says where its access keys are issued. Then enter the endpoint, bucket, region (if needed) and the keys.

**3. Watch the verification**

Ankra immediately checks the credentials against the bucket. A vault that passes shows **Ready**; one that does not shows **Failed** with the excerpt of what the bucket answered and a **Verify again** action - see [When verification fails](#when-verification-fails).

**CLI**

```bash theme={null}
ankra backup vaults create production-backups \
  --provider upcloud \
  --endpoint https://fi-hel2.upcloudobjects.com \
  --bucket ankra-prod-backups \
  --region fi-hel2
```

The access key ID and secret are prompted for when not passed as flags - the secret hidden - so they stay out of your shell history. Prefer the prompt over `--access-key-id` / `--secret-access-key`.

A vault that fails its first verification exits non-zero with the failure excerpt instead of a green create.

## Provider notes

| Provider | Endpoint shape | Notes |
| - | - | - |
| UpCloud Object Storage | `https://<region>.upcloudobjects.com` | Region is the endpoint prefix, for example `fi-hel2`. Note that *provisioning* takes a Managed Object Storage region instead - `europe-1`, `us-1` - which Ankra checks against your account |
| DigitalOcean Spaces | `https://<region>.digitaloceanspaces.com` | Spaces keys are separate from API tokens |
| Scaleway Object Storage | `https://s3.<region>.scw.cloud` | Uses the same key pair as the API |
| Hetzner Object Storage | `https://<region>.your-objectstorage.com` | Keys are issued in the console, not the cloud API |
| Amazon S3 | `https://s3.<region>.amazonaws.com` | Turn **path style** off |
| Other | Anything S3-compatible | MinIO, Garage, Ceph RGW; keep path style on |

## When provisioning fails or stalls

A vault Ankra provisions shows **Provisioning** until the bucket exists and its keys verify. Two things can go wrong, and both are recoverable the same way.

**It reads Failed with an excerpt.** The excerpt is what the provider answered - a region your account cannot use, a bucket name someone else holds, a token without the right scope. There is nothing to re-verify: the run never minted keys, so **Verify** is not offered and the API refuses it. Delete the vault - tick **Also destroy the bucket Ankra created**, or pass `--destroy-provider-resources`, so anything the run got as far as creating goes with it - and provision again with the excerpt's cause fixed.

**It stays on Provisioning.** Nothing retries a provisioning run, so a row that has not moved for quarter of an hour is stuck rather than slow, and the dashboard says so. Delete it the same way and try again.

## When verification fails

A **Failed** vault is still registered - nothing has to be redone from scratch - but the keys you gave it are never read back, so they cannot be edited in place. The recovery depends on what the excerpt says:

| Excerpt | Cause | Fix |
| - | - | - |
| `403 Forbidden` / `AccessDenied` | The key is valid but cannot reach this bucket | Fix the bucket policy or the key's permissions, then **Verify again** (`ankra backup vaults verify <name>`) |
| `InvalidAccessKeyId` / `SignatureDoesNotMatch` | The key pair is wrong | Delete the vault and add it again with the corrected keys |
| `NoSuchBucket` | The bucket name or region is wrong | Delete and re-add with the right bucket; on providers whose region is part of the endpoint, check the endpoint too |
| Connection or DNS errors | The endpoint is wrong or unreachable from Ankra | Check the endpoint URL (it must start with `https://`) and re-add, or fix the network path and **Verify again** |

**Verify again** re-runs the same check the create ran; the row updates in place with the new status and the time it last verified.

## Manage vaults

```bash theme={null}
ankra backup vaults list                       # every vault with status and last verification
ankra backup vaults get production-backups     # details, including a failure excerpt
ankra backup vaults verify production-backups  # re-run the credential check
ankra backup vaults delete production-backups  # confirms first; --yes to skip
```

`get`, `verify` and `delete` accept a vault name or id, and `list` / `get` support `-o json|yaml`. `verify` on a vault that is still provisioning answers that it is still being provisioned rather than recording a failed check.

## Deleting a vault

Deleting a vault removes Ankra's record of it and the access keys it stored. **By default the bucket is left exactly as it is** - with every restore point in it - along with anything Ankra created for it, so a deletion can never lose data on its own.

> [!WARNING]
>
> Nothing stops you deleting a vault that is still in use: Ankra does not yet refuse a delete on the grounds that something references the vault. Check before deleting one.

One exception, and it is deliberate: deleting a vault that is **still provisioning** always tears down the provider side, whether or not you ask for it. Such a vault has no restore points to lose, but the run may already have created a bucket or a provider resource - and once the record is gone nothing else can find them.

For a vault **Ankra provisioned**, you can ask for the cloud side to be cleaned up in the same step. Ankra then empties and deletes the bucket and removes what it minted for the vault - the UpCloud Managed Object Storage service, the DigitalOcean Spaces key. Scaleway and Hetzner vaults use your own credential's keys, which are never touched.

> [!WARNING]
>
> **This destroys data.** Every restore point in the bucket is gone, and nothing restores from that vault afterwards. Ankra refuses it for a bucket you registered yourself: that one is yours, and only you should delete it.

**Dashboard**

In the delete dialog, tick **Also destroy the bucket Ankra created**. The box is unchecked every time the dialog opens, names the bucket and its provider, and the confirm button becomes **Delete and destroy bucket**. A bring-your-own vault shows no such box.

**CLI**

```bash theme={null}
# Forget the vault; the bucket stays in your cloud account
ankra backup vaults delete offsite

# Forget the vault and destroy the bucket Ankra created for it
ankra backup vaults delete offsite --destroy-provider-resources
```

The confirmation prompt names the bucket before anything is destroyed. `--yes` skips it, so use that only in scripts that already know what they are deleting.

The teardown runs as a background job: the vault disappears from the list immediately and the bucket is removed shortly after. Each of its steps is written to be repeatable - a bucket already gone, a service already deleted and keys already removed all count as done - but nothing retries it automatically today. If the teardown fails, the provider resources stay and have to be removed in the provider console.

## Protect a stack

A vault is where restore points land; a stack's backup policy is what puts them there. Protection is a property of the stack, not a separate object: it is stored as the stack's own `backup` block, and the platform converges on it by installing the [backup data plane](https://docs.ankra.ai/concepts/backup-vaults.md#the-backup-data-plane) on the cluster.

Look at what a backup would have to carry first:

```bash theme={null}
ankra cluster stacks data list shop
```

That lists the stack's data assets - standalone persistent volume claims, and the databases an operator runs - under the names the selection uses.

**CLI**

```bash theme={null}
ankra cluster stacks protect shop \
  --vault production-backups \
  --schedule daily \
  --retention daily=7,weekly=4,monthly=6 \
  --include-pvc shop/data \
  --backup-now --wait
```

The command prints the policy it stored and then `Backup stack: installing` until the data plane is actually on the cluster, so nothing is called protected while the Velero that would do the protecting is still arriving. A capture started before then waits rather than failing.

A policy that cannot work is refused with every field-level reason at once, so a bad schedule and a bad retention are fixed in one edit:

```
The backup policy is not valid.
  - backup.schedule: 'evry day' is neither a five-field cron expression nor one of hourly, daily, weekly.
```

**Cluster file**

The same policy in your cluster file, applied with `ankra cluster apply -f cluster.yaml`:

```yaml theme={null}
stacks:
  - name: shop
    backup:
      enabled: true
      vault: production-backups
      schedule: daily
      retention:
        hourly: 0
        daily: 7
        weekly: 4
        monthly: 6
        yearly: 0
        minimum_count: 3
        minimum_age: 24h
      selection:
        databases: true
        persistent_volume_claims:
          - shop/data
        confirm_exclude_databases: false
```

Every field, with its default, is in the [`backup` block reference](https://docs.ankra.ai/reference/importcluster#spec-stacks-backup).

What `protect` takes:

| Flag | Meaning |
| - | - |
| `--vault` | **Required.** The vault restore points are written to, by name or id. A protected stack with nowhere to write to is not protected |
| `--schedule` | `hourly`, `daily`, `weekly`, or a five-field cron expression. Default `daily` |
| `--retention` | `key=value` pairs from `hourly`, `daily`, `weekly`, `monthly`, `yearly`, `minimum-count`, `minimum-age` |
| `--include-pvc` | Repeatable, `namespace/name`. Volumes are captured only where named |
| `--exclude-databases` | Leave the stack's databases out. Needs `--confirm-exclude-databases` beside it |
| `--backup-now` | Take the first restore point immediately instead of waiting for the schedule |
| `--wait` | Follow the first capture's run until the restore point is sealed |

Ankra takes the scheduled restore points itself, on the schedule the block names, through the same capture as **Back up now** - so every scheduled backup is a restore point you can list, restore and let retention expire. Nothing is scheduled inside the cluster for any engine: no Velero `Schedule`, no CloudNativePG `ScheduledBackup`, no schedule entry inside a Percona cluster. A Percona cluster is captured into the backup storage its own spec already declares.

For a CloudNativePG cluster, protecting the stack writes two things into it, because CloudNativePG writes a backup wherever the `Cluster` itself says: the barman-cloud archiver goes into the member that declares the `Cluster` (the manifest body, or `cluster.plugins` in the `cloudnative-pg/cluster` chart's values), and a stack member named `ankra-backup-policy-<stack>` holds the object store it archives into. Both are Ankra's: `unprotect` removes them, and a clone or a profile capture leaves them out of the copy while the source stack keeps them. An archiver you configured yourself - your own object store, an in-tree `spec.backup.barmanObjectStore`, the chart's own `backups` section - is left exactly as you wrote it, and Ankra reports that it cannot take restore points of that cluster into the vault: a restore point you take yourself is refused with the reason, and a scheduled backup is skipped with `archiver_unavailable` (as opposed to `archiver_not_wired` below, which means Ankra's own archiver is missing and a protect or manual restore point puts it back).

Four behaviours worth knowing before you rely on it:

* **Databases are in by default; volumes are not.** Protecting a stack does not start copying every claim in its namespaces. Name the volumes you want with `--include-pvc` or `selection.persistent_volume_claims`. Excluding databases from a stack that runs them needs an explicit acknowledgement, and leaves the stack carrying a standing warning.
* **An omitted block preserves protection.** A cluster file that does not mention `backup` leaves the stored policy alone, so an older CLI or a partial file cannot unprotect a stack. Removing protection is an explicit `enabled: false` or `ankra cluster stacks unprotect`, and the write warns about what stops being covered.
* **Protecting a CloudNativePG cluster restarts its instances once.** Ankra adds the barman-cloud archiver to the `Cluster`, and CloudNativePG reconciles that by rolling the instances one at a time - a brief primary failover. Only `protect`, `unprotect` and a restore point you take yourself do this; a scheduled backup never changes a database. If a stack's clusters lost the archiver (an `ankra cluster apply` that replaced the stack from a file without it, say), scheduled backups are skipped with `archiver_not_wired` until you protect the stack again or take a restore point by hand, and the restore point's answer says the instances restart.
* **A CloudNativePG restore point needs the stack protected, and lands in the stack's own vault.** The cluster archives into the object store its policy wired, so a restore point of it cannot be written anywhere else: `restore-points create` on an unprotected stack, or into another vault, is refused with the reason, and nothing is created. A restore point taken in the same minute as the first protect can fail while the instances restart; the next one succeeds.
* **Retention counts the schedule's restore points, not the ones you take by hand.** `daily=7` keeps the newest scheduled restore point of each of the last seven days. A restore point you take yourself - **Back up now**, or `restore-points create` - is kept for the policy's longest period (seven days under `daily=7`), and the safety restore point Ankra takes before an in-place restore is kept for seven days, so a restore stays undoable for a week. Neither one replaces that day's scheduled restore point, and taking another does not delete the one before it.

Per-add-on overrides ride the add-on's settings, for the case where one add-on in a protected stack should be captured differently (or not at all):

```bash theme={null}
ankra cluster addons settings get cnpg-cluster
ankra cluster addons settings set cnpg-cluster --backup-enabled=false
```

## Take a restore point now

```bash theme={null}
ankra cluster stacks restore-points create shop --note "before the 3.2 upgrade" --wait
```

The capture is dispatched by the platform, so without `--wait` the command answers with the restore point in `creating` and the run that will seal it. `--wait` follows that run and prints the sealed restore point.

The vault is resolved in order: `--vault`, then the stack's own policy, then the organisation's single ready vault. With more than one ready vault and nothing naming which, the request is refused rather than chosen for.

The selection resolves the same way - the request's own `--include-pvc` / `--exclude-databases`, then the stack's stored selection, then the default of databases in and volumes only where named. A request that carried no selection never widens to everything.

## See what a restore point holds

```bash theme={null}
ankra cluster stacks restore-points list shop                      # newest first
ankra cluster stacks restore-points list shop --status complete
ankra cluster stacks restore-points list shop --trigger scheduled --limit 10
ankra cluster stacks restore-points get shop 0b2f                  # an unambiguous id prefix is enough
ankra backup restore-points list --cluster production              # across every cluster
```

`get` adds the manifest, every asset in it, and the run that produced it. `list` pages with `--cursor`; `--vault` narrows to one vault, and `ankra backup restore-points list` takes `--cluster` and `--stack`.

> [!WARNING]
>
> **Read the `Not carried` list before you rely on a restore point.** Every listing and every detail read prints it, next to what the restore point does contain - a volume outside the selection, a data engine no adapter covers, an external service that lives outside the cluster - each with the reason and the remedy. An omission nobody read is the same as an omission nobody was told about.

An id prefix is resolved against the stack's 200 most recent restore points, so it is checked for ambiguity only within that window. The full id is what addresses an older restore point with certainty.

## Restore a stack in place

> [!WARNING]
>
> **This destroys before it replaces.** The restore removes the stack's current volumes before it writes the restore point's. Confirmation is typing the stack's own name, not `y/N`.

```bash theme={null}
ankra cluster stacks restore-points restore shop 0b2f --wait
```

The platform accepts the restore and answers with the sequence it will follow, which the command prints before any of it runs:

1. Scale down the workloads in the stack that own the data being restored.
2. Remove the volumes the restore point replaces, so the restored data is not written beside the old data.
3. Restore the restore point's assets onto the cluster through the backup data plane.
4. Scale the workloads back up over the restored data.

`--yes` skips the typed confirmation for scripts. `--force` is needed when the stack's data has changed since the restore point was taken: the refusal compares the restore point's assets against the stack's current inventory, and **an inventory whose live database scan did not run counts as drift**, because "we could not read it" is not "it is unchanged".

> [!WARNING]
>
> **CloudNativePG and Percona databases cannot be restored in place yet.** A restore point carrying one is refused with `Restoring this restore point in place is not supported yet: it carries a database this platform cannot yet recreate in place.` The ordinary restore path would report success over unchanged data, which is worse than refusing - see [Restoring in place](https://docs.ankra.ai/concepts/backup-vaults.md#restoring-in-place). Volumes captured by Velero and databases captured as logical dumps, including every `ankra migrate` import, restore in place today.

A restore is also refused against a cluster that is offline or stopped - the sequence destroys before it replaces, so it must not start against a cluster nobody can reach - and against a restore point that is not `complete`.

## Unprotect a stack

```bash theme={null}
ankra cluster stacks unprotect shop
```

Confirmation is the typed stack name again; `--yes` skips it. Turning protection off stops future backups and removes the rendered schedules on the next render. **Every restore point already taken is kept and stays restorable** - removing protection is a decision about the future, not about the past. The `ankra-backup` system stack is not removed either, because those restore points are restored through it.

## Follow a run

Every capture and every restore is a run, and a run has a step for each thing it does. Runs are organisation-scoped, so one listing covers every cluster.

```bash theme={null}
ankra runs list --kind backup --cluster production
ankra runs list --status failed
ankra runs get <run-id>            # the plan, and every attempt of every step
ankra runs cancel <run-id>
ankra runs retry <run-id>          # opens a NEW run from the step that failed
```

`retry` answers with the new run, not the old one: the failed row will never move again. `list` takes `--stack`, `--cursor` and `--limit`, and every command supports `-o json|yaml`.

## Backup posture

Posture is the answer to "is this data protected, and if not, why", rendered wherever someone could lose data: a **Protected** / **Unprotected** / **Protection unknown** pill on stack headers, stack cards and the Stack Builder, a backup posture card on the cluster overview, a fleet widget on the organisation dashboard, and a **Protect your stateful stacks** milestone on the setup checklist once the organisation runs something stateful.

| State | What it means | What to do |
| - | - | - |
| **Protected** | An enabled policy naming a vault that is ready | Nothing. Check the restore points are actually landing |
| **Unprotected** | No policy; or the vault it names is missing, provisioning or in error; or databases are excluded from a stack that runs them; or the stack holds no data at all | The reason says which. A stack with no data assets is unprotected but not a finding |
| **Unknown** | The `backup` block did not decode, the vault lookup could not be answered, or the cluster's inventory has not landed | Check the cluster is online and reporting; an unknown is never reported as unprotected |

An organisation with no vault at all gets a call to action rather than a report that everything is exposed, and a posture that has not loaded renders nothing rather than flashing a verdict it does not have.

## Troubleshooting

| What you see | Cause | Remedy |
| - | - | - |
| `Backups are not enabled for this organisation.` | The **backups** feature is switched off for the organisation the CLI is acting on | Check `ankra org current` first, then [contact support](https://docs.ankra.ai/platform/support.md). See [Not enabled yet?](#not-enabled-yet) |
| `This backup vault has not verified; re-verify it before taking a restore point.` | The vault's last credential check failed or never ran | `ankra backup vaults verify <name>`, and [When verification fails](#when-verification-fails) for what the excerpt means |
| `This organisation has more than one ready backup vault; name the one to write to.` | The request named no vault, the stack has no policy, and there is more than one candidate | Pass `--vault <name>`, or protect the stack so its policy names one |
| `This organisation has no ready backup vault to write a restore point to.` | No vault is `ready` | Register or provision one, above |
| `This selection covers none of the stack's data, so the restore point would carry nothing.` | The selection excluded everything the stack holds | `ankra cluster stacks data list <stack>` to see the asset names, then widen the selection |
| `This stack's data has changed since the restore point was taken` | Drift between the restore point and the live inventory, **or** an inventory whose database scan did not run | Take a fresh restore point, or restore with `--force` if the drift is expected |
| `Restoring this restore point in place is not supported yet` | The restore point carries a CloudNativePG or Percona database | Not yet available. The capture is still good and the databases are still in the vault |
| `Only a complete restore point can be restored.` | The restore point is `creating` or `failed` | `ankra runs get <run-id>` on the run that was sealing it |
| `This cluster is not online, so its data cannot be restored right now.` | The target cluster is stopped or its agent is not connected | Bring the cluster back, then retry |
| `A backup, restore or clone is using this restore point` | A delete raced a run that is reading the restore point | Wait for the run to finish, or `ankra runs cancel <run-id>` |
| `Backup stack: installing` never becomes `ready` | The cluster's agent is too old to run the backup jobs, or a resource name the backup stack needs is already taken by a user-authored resource | Upgrade the [cluster agent](https://docs.ankra.ai/concepts/cluster-agent.md); rename the colliding resource. `ankra runs list --cluster <name>` shows steps that never got claimed |
| `Its objects were left in the bucket: ...` after a delete | No sweep could be dispatched - the source cluster is gone, the vault is gone, or the agent does not carry the object-delete job | The restore point row is removed either way. Remove the objects from the bucket yourself so you stop paying for them, or upgrade the agent and let the retention sweep take them |

> [!NOTE]
>
> Diagnose all of this with the Ankra CLI, not `kubectl`. The backup data plane is a stack Ankra owns and reconciles, so a change made against the cluster directly is reverted on the next render.

## Permissions

| Permission | Allows |
| - | - |
| `backups.read` | Seeing vaults, policies, restore points, runs and posture |
| `backups.operate` | Verifying a vault; taking restore points and running restores |
| `backups.manage` | Creating and deleting vaults; protecting and unprotecting stacks; deleting restore points |

Organisation admins hold all three. A member with only `backups.read` sees the vault list read-only; the page says so and names the permission an admin has to grant for adding, verifying or deleting a vault. Both gates - the organisation's **backups** feature and the permission - are checked in that order, so an organisation without the feature answers the same way whatever the caller may do.

## Not enabled yet?

Backups are on for every organisation unless the **backups** feature has been switched off for yours. While it is off:

* The **Backups** settings page renders an explanation instead of the vault list, and no protection pill, posture card or fleet widget appears anywhere.
* `ankra backup …`, `ankra cluster stacks protect|unprotect|restore-points|data …` exit non-zero with `Backups are not enabled for this organisation.` followed by what to do about it. A real permission refusal on the same commands keeps its own wording, so the two are never confused.
* The API answers `403` with that same text on every backups route, browser and token alike - a personal access token cannot reach the lane in an organisation where it is dark.
* A `backup` block in a cluster file is rejected on apply with the same sentence.

Two things to check before asking for it to be enabled:

1. **The right organisation is selected.** The CLI acts on the current organisation - `ankra org current` shows which, and `ankra org switch <name>` changes it.
2. **The account is in the organisation that was enabled.** Enablement is per organisation, not per user.

Then [contact support](https://docs.ankra.ai/platform/support.md) to have the **backups** feature enabled for the organisation.

## Command reference

The generated CLI reference carries every flag and default of these families:

| Family | Reference |
| - | - |
| `ankra backup vaults`, `ankra backup restore-points` | [ankra backup](https://docs.ankra.ai/reference/cli/backup.md) |
| `ankra cluster stacks data`, `protect`, `unprotect`, `restore-points` | [ankra cluster](https://docs.ankra.ai/reference/cli/cluster.md) |
| `ankra runs` | [CLI command reference](https://docs.ankra.ai/reference/cli/index.md) |

> [!NOTE]
>
> The reference is regenerated from the CLI source on each release, so the restore-point families appear there from **v0.17.0**. Until then `ankra <command> --help` is the authority on a flag.

## Next steps

> **[Backup vault concepts](https://docs.ankra.ai/concepts/backup-vaults.md)**
>
> How vaults, policies, restore points, runs and posture fit together.

> **[The backup block](https://docs.ankra.ai/reference/importcluster.md#spec-stacks-backup)**
>
> Every field and default of a stack's backup policy, in the cluster file.

> **[Clone stacks between clusters](https://docs.ankra.ai/guides/clone-stack.md)**
>
> Clone a stack's configuration today - data follows via restore points.

> **[Move a Docker deployment in](https://docs.ankra.ai/guides/migrate-from-docker.md)**
>
> `ankra migrate` carries databases through the same vault.


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