Exporting and Migrating

This feature is in the Early Access stage and under active development. Configuration schemas and behavior are subject to change. We recommend that you do not use this feature in production environments.

Two commands produce a declarative-config repo from something that already exists: sam config pull exports a running Platform service, and sam config migrate converts older configuration files. This page covers both. For the workflow that applies a repo once you have one, see Planning and Applying Changes.

Export Running State with Pull

sam config pull serializes a Platform service's running state into resource YAML and writes a manifest alongside it. Use it to bootstrap a repo from an existing deployment, to confirm what is running, or to move configuration from one deployment to another:

sam config pull -o ./pulled --url https://platform.example.com

The -o (--output) directory is required. Pull writes one file per resource under the usual kind directories, plus a generated manifest that lists everything it exported.

Authenticating a Pull

Pull often runs without a manifest, so it accepts credentials on the command line. Against a protected Platform service in a pipeline, the most direct option is the SAM_PLATFORM_TOKEN environment variable, which pull honors the same way plan and apply do:

SAM_PLATFORM_TOKEN="${SAM_PLATFORM_TOKEN}" \
  sam config pull -o ./pulled --url https://platform.example.com

To name the variable yourself instead of using SAM_PLATFORM_TOKEN, set the auth type and the environment variable that holds the token:

sam config pull -o ./pulled --url https://platform.example.com \
  --auth-type bearer --auth-env PLATFORM_TOKEN

You can also pull from a target you signed in to with sam auth login by passing --target <name> in place of --url. For the full credential model and precedence, see Targets and Authentication.

Restricting What You Pull

Restrict the export to one kind with --only, and to a single resource with --name:

sam config pull -o ./pulled --url https://platform.example.com --only agent
sam config pull -o ./pulled --url https://platform.example.com --only model --name general

Writing Into an Existing Directory

By default, pull refuses to write into a non-empty directory so it never clobbers work in progress. Two flags override that:

  • --force wipes the output directory before writing.

  • --merge rewrites only the files for resources that exist on the Platform service, leaving your other files in place.

Use --manifest-name to control the generated manifest's filename instead of the default timestamped name.

When Pull Fails

Pull writes everything or nothing. It fails, and writes no files, in any of the following cases:

  • A toolset configuration or bundle, or a connector spec, fails to download, or a toolset's stored bundle is empty.

  • An RBAC role, grant, claim mapping, or system user cannot be written as a file, for example because it refers to a role that pull cannot resolve.

  • A skill or toolset name contains / or \, or starts with a dot.

  • Two resources of the same kind, such as agents named Sales/EMEA and sales_emea, map to the same filename. Pull compares filenames without regard to case.

  • A request to list the resources of a kind, or the Platform service's default roles, fails.

For every kind except skills and toolsets, pull still exports a resource whose name contains / or \, or starts with a dot. It replaces each / and \ in the filename with _ and removes any leading dots. The name field in the file keeps the original name. If two budgets or two claim mappings map to the same filename, pull adds a numeric suffix to one of them instead of failing.

Pull warns instead of failing, and leaves the following out of the output:

  • Every kind whose feature is disabled on the Platform service.

  • Built-in roles.

  • Files attached to a dataset example.

  • The bundle of a toolset or skill that has none uploaded. Pull writes the resource's metadata only.

  • The configuration of a toolset whose discovery status is not ready.

  • The users of a budget when the token lacks rbac:_:read, or when an assignee has no identity that a budget file can name. Pull writes the budget without users, so sam config apply leaves its assignments unmanaged.

  • A custom system user that declarative config cannot manage, and the role grants that widen a built-in system user's roles. Pull names each one so that you can manage it through the Platform service API.

  • A skill whose bundle fails to download or unpack. Pull keeps the skill in the manifest and leaves any existing skills/<name>/ directory unchanged, even with --force. If there is no local copy, sam config plan and sam config apply fail for that skill until you add skills/<name>/ or remove the skill from the manifest.

The Round-Trip Property

Re-applying a pulled repo produces no further changes to non-secret fields. A pull followed by an apply against the same Platform service is a no-op: it is the reliable way to confirm that what you applied is what is running. After a pull, run sam config plan to see that the diff is empty, then commit.

Secrets Come Back as Placeholders

The Platform service never returns stored secrets in the clear, so pull cannot write real credentials into your files. Instead it rewrites known credential fields into ${KIND_NAME_FIELD} placeholder variables and lists them at the end of the run. Export those variables before you re-apply, and the pulled repo stays safe to commit. See Secrets and Variables for the substitution model.

Skills follow the same pattern. Pull writes the credentials that the Platform service redacts from a skill's tools: block as ${SKILL_<SKILL>_<TOOL>_<FIELD>} placeholders. The Platform service redacts only the values that it recognizes as credentials. For more information about which values it recognizes, see Credentials in a Stored Skill.

Rounding Imports Back to Imports

If the repo you applied imported resources from other repositories, point pull at that manifest with --reference so it carries the sources block forward and writes imported resources back as name@source entries rather than expanding them into local files:

sam config pull -o ./pulled --url https://platform.example.com --reference manifest.yaml

For access-control kinds, --include-yaml-preview additionally emits any operator-owned, file-defined roles as commented-out preview blocks, so you can see them without adopting them into the repo.

Migrate Older Configuration

If you have configuration in the older format that earlier releases shipped, sam config migrate converts it into clean resource YAML in a new directory. It runs entirely offline and never contacts a Platform service:

sam config migrate ./legacy-config ./migrated

Migrate writes a report grouped into four buckets: what it migrated, what it migrated with warnings, what it skipped, and what errored. Anything it cannot map cleanly is preserved for manual review rather than dropped. Write the report to a file with --report:

sam config migrate ./legacy-config ./migrated --report migration-report.json

Treat the output as a starting point, not a finished repo. Review the report, re-home anything that belongs to the environment rather than the resource (authentication, identity, event broker connection), then run sam config plan against a Platform service before you trust it.

Related Topics