> For the complete documentation index, see [llms.txt](https://docs.kangal.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kangal.dev/configuration-and-automation/configuration.md).

# Configuration lifecycle

Kangal's Admin API can export a tenant's declarative configuration, validate it offline or server-side, compare it with live state, import selected resources, synchronize a bundle, and create or roll back tenant snapshots.

Use these workflows for controlled promotion and recovery, not as a substitute for database backups. Imports are sequential and are not wrapped in one database transaction; a failure late in an import can leave earlier resources applied.

## Configuration bundle

A bundle is JSON or YAML with an optional `tenant_id` and resource arrays:

```yaml
tenant_id: tenant-acme
gateways: []
services: []
routes: []
upstreams: []
targets: []
redis_configs: []
certificates: []
ca_certificates: []
snis: []
vaults: []
consumers: []
consumer_credentials: []
ai_gateway_configs: []
metrics: []
```

Only include resource arrays you intend to manage. Import does not delete a live resource merely because it is absent from the bundle.

## API workflow

The safest promotion path is:

1. Export the target tenant and store the artifact securely.
2. Validate the desired bundle with strict reference checks.
3. Diff desired state against the live tenant.
4. Run sync in dry-run mode and review validation, counts, and proposed changes.
5. Apply sync with a pre-apply snapshot and an operator note.
6. Export again and compare the resulting state.
7. Roll back only after understanding snapshot and secret limitations.

The main endpoints are:

| Method and path                                     | Behavior                                                          |
| --------------------------------------------------- | ----------------------------------------------------------------- |
| `GET /api/v1/admin/config/export`                   | Export a tenant bundle as JSON or YAML.                           |
| `POST /api/v1/admin/config/validate`                | Validate a supplied JSON/YAML bundle.                             |
| `POST /api/v1/admin/config/diff`                    | Compare desired bundle with live tenant state.                    |
| `POST /api/v1/admin/config/import`                  | Insert or overwrite matching resources; apply is the API default. |
| `POST /api/v1/admin/config/sync`                    | Validate, diff, optionally snapshot, then import.                 |
| `POST /api/v1/admin/config/snapshots`               | Snapshot the supported tenant configuration bundle.               |
| `GET /api/v1/admin/config/snapshots`                | List tenant snapshot summaries.                                   |
| `POST /api/v1/admin/config/snapshots/{id}/rollback` | Validate or apply a snapshot import.                              |

All configuration routes require an admin bearer token. Because validation, diff, dry-run, snapshot creation, and rollback preview are implemented as `POST`, they require a writer role or `admin:write` Admin API scope even when no live resource is changed. Export and snapshot listing require read access.

The `tenant_id` value explicitly selects the configuration target. Use a tenant-scoped token, keep query and body tenant values equal to the intended tenant, and verify the active context before every write. Sync rejects a query/payload tenant mismatch.

## JSON and YAML

For YAML request bodies use `Content-Type: application/yaml` or `?format=yaml`. Select a YAML export with `Accept: application/yaml` or `?format=yaml`.

```bash
curl -fsS \
  -H "Authorization: Bearer $KANGAL_TOKEN" \
  -H 'Accept: application/yaml' \
  "$KANGAL_URL/api/v1/admin/config/export?tenant_id=$TENANT_ID" \
  -o tenant-acme.yaml

curl -fsS -X POST \
  -H "Authorization: Bearer $KANGAL_TOKEN" \
  -H 'Content-Type: application/yaml' \
  "$KANGAL_URL/api/v1/admin/config/validate?strict=true" \
  --data-binary @tenant-acme.yaml | jq
```

Malformed JSON/YAML returns `400`. A structurally valid body that fails request-model validation normally returns `422`. Configuration validation or diff preconditions can return `400` with details.

## Identity matching

Import uses declarative identity fields to decide whether a resource already exists:

| Resource                                       | Matching identity                  |
| ---------------------------------------------- | ---------------------------------- |
| Gateway                                        | tenant + name                      |
| Service                                        | tenant + gateway + name            |
| Route                                          | tenant + gateway + path            |
| Upstream                                       | tenant + gateway + name            |
| Target                                         | tenant + gateway + upstream + name |
| Redis config, certificate, CA certificate, SNI | tenant + gateway + name            |
| Vault                                          | tenant + gateway + prefix          |
| Consumer                                       | tenant + username                  |
| Consumer credential                            | consumer + type + key              |
| AI gateway config                              | tenant + gateway + kind + name     |
| Metric                                         | gateway ID                         |

With `overwrite: false`, a matching live resource is skipped. With `overwrite: true`, the matching document is replaced by the desired resource, or inserted when missing. Review defaults carefully: direct API import defaults to `dry_run=false` and `overwrite=false`; API sync defaults to `dry_run=true`, `overwrite=true`, `strict=true`, and `snapshot_before_apply=true`.

## Secret handling

Public export redacts plaintext secrets. A redacted placeholder is safe for review, but it is not a recoverable secret. The importer does not provide a general promise that a redacted placeholder preserves the previous value during overwrite.

Therefore:

* Never apply a redacted export with `overwrite=true` without restoring controlled secret references or intended values.
* Prefer vault/secret references and separate secret delivery over plaintext in bundles.
* Store exports and snapshots as sensitive artifacts even after redaction; topology, consumer IDs, routes, and certificates remain operational data.
* Test rollback in a non-production tenant with representative credentials before relying on it for recovery.

Configuration snapshots store the exported bundle fields listed on this page. Pre-apply sync snapshots are built from the same export path, so the same redaction caution applies to rollback. Protect other administrative data with its own API export and database backup procedure.

## Limits and behavior

* Snapshot list `limit` defaults to 20 and is capped at 100. It returns a plain array, not shared list pagination headers.
* Snapshot versions increment within a tenant and include a SHA-256 checksum and per-resource counts.
* Strict validation upgrades missing service/upstream references from warnings to errors.
* Import processes non-empty resource collections in order and does not remove resources omitted from the desired bundle.
* Snapshot rollback reuses validation and import behavior; it is not a transactional database rewind.

## Tool choice

Use [`kangalctl`](/configuration-and-automation/kangalctl.md) for context management, local validation, diff, export, import, sync, and CRUD. Use the Admin API commands in [Import, export, and rollback](/configuration-and-automation/import-export-rollback.md) for snapshot create/list/rollback.

## Operational checklist

Before apply:

* Confirm API URL, current context, token scope, and tenant.
* Keep a database backup in addition to a configuration snapshot.
* Restore intended secrets or secret references into the desired artifact.
* Run local validation, server strict validation, diff, and sync dry-run.
* Review every `would_insert`, `would_update`, and `would_skip` count.
* Confirm that omitted resources are intentionally left unchanged.

After apply:

* Export live state and compare it with desired state.
* Exercise one route per changed gateway and inspect recent traffic.
* Check application logs, Admin API errors, and audit records.
* Record snapshot ID, operator, source revision, and verification result.

## Troubleshooting

| Symptom                                              | Resolution                                                                                                                  |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Validate/diff returns `403` with a read token        | These are `POST` routes and require `admin:write`.                                                                          |
| YAML parses as invalid JSON                          | Send `Content-Type: application/yaml` or add `?format=yaml`.                                                                |
| Strict validation fails on a reference               | Add the referenced service/upstream to the bundle or correct the identifier.                                                |
| Import did not update existing resources             | Set `overwrite=true`; preview first.                                                                                        |
| Import did not delete resources absent from the file | Expected: import is additive/replacing, not pruning. Delete resources explicitly through their Admin API.                   |
| Sync rejects tenant mismatch                         | Make query and body `tenant_id` identical, and verify the active token's tenant.                                            |
| Rollback restores `[redacted]` instead of a secret   | Stop traffic to the affected integration and restore controlled secret values/references; snapshots are not secret backups. |
| Apply failed midway                                  | Treat state as partially applied, export live state, diff it, and choose a forward fix or tested rollback.                  |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kangal.dev/configuration-and-automation/configuration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
