Home / Docs / Manifests
Manifests
In Yggdrasil everything is a versioned manifest — a workflow, an integration type, a deployed instance, a team, even the shape of the control plane itself. You describe the desired state as a declarative document, apply it, and the core keeps every version with history, checksum and the ability to roll back. It's real GitOps for operating your platform.
What a manifest is
A manifest is a YAML (or JSON) document with the same shape you know from Kubernetes — deliberately, because it's the pattern most teams already master. The envelope has four parts:
apiVersionyggdrasil.io/v1alpha1. The core accepts multiple apiVersions during deprecation windows.kindspec (see the list below). It's normalized to lowercase before validation.metadataname (required), namespace (defaults to global), description, labels and active. The triple (kind, namespace, name) is the logical identity of the resource across all of its versions.speckind (required). It's the only part whose format changes from one kind to another.The model is declarative: you don't say how to get there, you say what the desired state is. The core reconciles. Unlike k8s, Yggdrasil versions every write — each apply with a change produces a new version, and the history stays queryable.
The kinds
Each accepted kind maps to a dedicated spec validator. These are the types supported today:
| Kind | What it's for |
|---|---|
integration_family | An interface contract (shared operations and schemas) that many providers implement. |
integration_type | A concrete implementation of a family (kubernetes, aws, github…), with its reactors. |
integration_instance | The deployed configuration of a type — credentials, cluster, project. |
integration_quickstart | An adopter-facing manifest: "install this with one command", with inputs and steps. |
product | A set of integrations/workflows delivered as a single unit. |
workflow | A step-by-step pipeline of operations across integrations. |
workflow_template | A parameterized workflow blueprint, instantiated on demand. |
surface | An internal console/panel that renders slices of the platform. |
rbac | A subject-action-resource access policy. |
policy | A runtime policy with conditions (rate limit, data residency…). |
resource | A tracked entity, originated by the core or discovered in an integration (an S3 bucket, a channel). |
repository_binding | A binding between a source repository and an integration or product. |
guardian_policy / guardian_approval / guardian_memory | The approval flow and its history. |
remediation_bundle / remediation_contract | Pieces of the incident-response flow. |
control_plane | Declares the shape of the production deploy (image, replicas, Postgres, ingress, transports). |
tenant | A tenancy boundary for multi-tenant deploys. |
ephemeral_environment | An ephemeral-environment definition (preview / PR environments). |
A kind outside this list is rejected with unsupported manifest kind — the core never persists anything it can't validate.
Versioning
An apply never overwrites anything: it appends a version. When it receives a manifest, the core:
- Normalizes and validates the envelope. It requires
apiVersion,kind,metadata.nameand a non-emptyspec; it trims/lowercases and applies thekind's validator to thespec. A failure here returns422— nothing is written. - Computes the new version number as
MAX(version) + 1within the triple(kind, namespace, name). The first time a resource is applied it's version1. - Promotes the new version to active and deactivates the previous one (
active = FALSE) in the same transaction. Applying withmetadata.active: falsewrites a "tombstone" without leaving any active version. - Persists a deterministic SHA-256
checksumof the normalized document, so that re-applying identical content is detectable (thediffreports "no changes").
Because every old version stays in the table with its spec intact, the history is complete: you can fetch any version by (kind, namespace, name, version) and never lose a resource's prior shape.
A manifest in practice
A minimal integration_quickstart — the manifest that makes an integration installable with one command. Note the envelope (apiVersion + kind + metadata + spec) and how the spec carries the fields specific to the kind:
apiVersion: yggdrasil.io/v1alpha1
kind: integration_quickstart
metadata:
name: slack
namespace: global
description: "Connect a Slack workspace in one command"
labels:
team: platform
spec:
display_name: Slack
providers:
# each provider becomes an "install this" in the console
- id: slack-bot
display_name: Slack Bot
requires:
- kind: integration_type
name: slack
inputs:
- id: bot_token
label: Bot token
type: string
required: true
sensitive: true
steps:
- id: create-instance
uses:
kind: integration_instance
with:
token: "{{ .inputs.bot_token }}"
The lifecycle
You drive everything through the CLI, which is thin: it just shapes the HTTP call to the core, which is the authority. The day-to-day flow:
Each subcommand maps to an operation in the core. Note that rollback isn't a dedicated endpoint: since every version keeps its spec, rolling back is simply re-applying the target version's spec as a new version — the history never moves backward.
$ yggdrasil apply -f slack-quickstart.yaml --dry-run
~ integration_quickstart global/slack (dry-run, not applied)
$ yggdrasil apply -f slack-quickstart.yaml
created integration_quickstart global/slack (version 1)
$ yggdrasil get integration_quickstart -n global
KIND NAMESPACE NAME VERSION ACTIVE
integration_quickstart global slack 1 true
$ yggdrasil describe integration_quickstart slack -n global # prints the manifest as YAML
$ yggdrasil rollback integration_quickstart slack --to 1 --yes
✓ rolled back integration_quickstart global/slack to the contents of v1 (new version 3)
$ yggdrasil delete integration_quickstart slack --soft # keeps the history, active=false
Real flags worth knowing:
apply -f <file> --dry-run-f - reads from stdin; multiple documents separated by --- in a single file.diff -f <file>get [<kind>] -n <ns> -o table|yaml|json --active-only--active-only filters to active ones only.describe <kind> <name> -n <ns>rollback <kind> <name> --to <version> -n <ns> --yesspec as a new version. --yes skips the confirmation.delete <kind> <name> [--soft] -n <ns> --yes--soft sets active=false on all versions, preserving the history; without it the delete is hard (removes every version of the logical identity), mirroring the core's default.workflow manifest turns into execution, and Integrations for the four-layer model (family → type → instance → provider).