# CI/CD lifecycle

Feature under active development
CI/CD version management is actively evolving. This documentation is continuously updated as the feature matures.
Always verify with the latest API reference or release notes before implementing in production.

This page walks you through the **practical steps** of using Mosaic’s Version Management APIs to move tenant configurations across environments.

It covers the full lifecycle: export, review, validate, and import — including caveats such as alias handling, concurrency, and audit logging.

## Phase 1: Export

To perform an export, call the [export API](/openapi/version-management/version-management.openapi/other/versioncontroller_export) against the **source tenant** and provide a valid access token for that tenant (issued using management app credentials).

```curl
 curl -i -X GET \
  'https://version-management.transmitsecurity.io/version/export/<SOURCE_TENANT_ID>?format=zip' \
  -H 'Authorization: Bearer <MANAGEMENT_APP_ACCESS_TOKEN>'
```

Curate token structure
When generating an **admin access token** for Version Management APIs, **do not** include the `resource` parameter. Version Management requires a **non-resource-scoped** token.

Environment URLs
Align the URL to the appropriate endpoint for your use case:

- `https://version-management.sbx.transmitsecurity.io` - Sandbox environment
- `https://version-management.transmitsecurity.io` - Production environment (US)
- `https://version-management.ca.transmitsecurity.io` - Production environment (CA)
- `https://version-management.eu.transmitsecurity.io` - Production environment (EU)
- `https://version-management.au.transmitsecurity.io` - Production environment (AU)


The response is a binary ZIP payload. When using curl, you may want to redirect the output to a file (for example, with `--output export.zip`).

Working with the ZIP export
The API response is a ZIP archive.
To inspect or version the configuration, **extract the ZIP contents** before reviewing or committing them to Git.
The same structure must be preserved if you later re-zip the bundle for import.

Each export always includes the complete configuration of the tenant, along with aliases for environment variables, keys, credentials, and certificates. **Sensitive values are never included.**

A `manifest.yaml` file is also included, with details about the database versions of the Journey module entities, and Identity Management data. These details are useful during validation (see [Phase 3: Validate](#phase-3-validate)).

## Phase 2: Review data

After generating an export, **store the package in a version control system** such as Git. Use pull requests and protected branches to review changes before promotion to the next environment. Version control provides a clear history of configuration changes and helps identify regressions. Be sure to keep dependencies intact (for example, journeys and their external connections) to avoid broken references during import.

**Use GitHub or another version control system to manage your exports**. Keep bundles private and never store secret values in Git.

Managing ZIP exports in Git
When storing exports in Git, **extract the ZIP file before committing** so that YAML changes can be reviewed and diffed easily.
Before importing, **re-zip the folder structure exactly as exported** (including `manifest.yaml` and all subfolders) to maintain compatibility with the import API.

### Suggested practice: curate full exports before import

Exports are **full snapshots** of the tenant so you have complete visibility of all objects (journeys, sub-journeys, external connections, etc.).
If you don’t want to promote certain items (e.g., deprecated or blocked journeys), we recommend **curating the export outside of Git** with dedicated scripts and checks, and committing to Git **only the curated, official version**. This keeps the repository history linear and clean.

**Recommended flow**

1. **Export** from the source tenant (full snapshot).
2. **Curate outside Git**: run project-specific scripts to remove obsolete or out-of-scope files (e.g., junk artifacts not needed for import). Note: Do not rename or restructure exported files — IDs and file names must remain unchanged, otherwise the import will fail. For configuration updates, make the changes in the Admin Portal before exporting (**do not edit the exported file directly**).
3. **Review the curated set** (locally or in a staging area), then **commit/merge to Git** only the curated version.


Why scripts, not just `validate`?
Version validation (see Phase 3) checks structure, version compatibility and presence of aliases, but **cannot know your product rules** (e.g., which journeys are deprecated or must never be promoted).
Your curation scripts implement **project governance**: they decide what is in-scope, what to drop, and how to normalize before promotion.

Heads-up
If you remove files, ensure you don’t break dependencies (e.g., a journey that still references a pruned external connection). Always re-run `/version/validate` after curation.

## Phase 3: Validate

Before applying a configuration, use the [version validation API](/openapi/version-management/version-management.openapi/other/versioncontroller_validate) in the **target tenant** with the exported data.

```curl
curl -X 'POST' \
  'https://version-management.transmitsecurity.io/version/validate/<TARGET_TENANT_ID>?format=zip' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer <MANAGEMENT_APP_ACCESS_TOKEN>' \
  -H 'Content-Type: application/zip' \
  --data-binary '@export.zip'
```

Environment URLs
Align the URL to the appropriate endpoint for your use case:

- `https://version-management.sbx.transmitsecurity.io` - Sandbox environment
- `https://version-management.transmitsecurity.io` - Production environment (US)
- `https://version-management.ca.transmitsecurity.io` - Production environment (CA)
- `https://version-management.eu.transmitsecurity.io` - Production environment (EU)
- `https://version-management.au.transmitsecurity.io` - Production environment (AU)


Note
When sending ZIP files with `curl`, use `--data-binary` to ensure the payload is transmitted intact.

Validation checks that:

- all required aliases (environment variables, keys, certificates, credentials) exist and have values,
- the exported configuration is structurally valid,
- and it is compatible with the target tenant’s version.


Note that **this phase does not run the full import logic — it only validates prerequisites and structure**. This means validation may pass even if the subsequent import encounters issues.

Review the validation report carefully and fix any problems (e.g., missing variables or version mismatches). **Repeat validation until the report is clean** before proceeding with the import.

## Phase 4: Import

Once validation passes, run the [import API](/openapi/version-management/version-management.openapi/other/versioncontroller_import) in the **target tenant** to apply the configuration. The import operation replaces the tenant’s configuration with the content of the file.

ZIP structure required
When importing, the file must be a **ZIP archive with the same structure as the original export** (including all subfolders and `manifest.yaml`).
Incorrect structure or missing files may cause the import to fail.

**Optional: rollback on failure** — You can pass the query parameter `failureRollBack=true` to request that, if the import fails or only partially completes (e.g. one module import succeeds but another fails), the system **automatically** reverts the target tenant to its state before the import. The response may include a `rollbackResult` object with the outcome (e.g. success or failure and a message).

```curl
curl -X 'POST' \
  'https://version-management.transmitsecurity.io/version/import/<TARGET_TENANT_ID>?format=zip&failureRollBack=true' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer <MANAGEMENT_APP_ACCESS_TOKEN>' \
  -H 'Content-Type: application/zip' \
  --data-binary '@export.zip'
```

Environment URLs
Align the URL to the appropriate endpoint for your use case:

- `https://version-management.sbx.transmitsecurity.io` - Sandbox environment
- `https://version-management.transmitsecurity.io` - Production environment (US)
- `https://version-management.ca.transmitsecurity.io` - Production environment (CA)
- `https://version-management.eu.transmitsecurity.io` - Production environment (EU)
- `https://version-management.au.transmitsecurity.io` - Production environment (AU)


Note
When sending ZIP files with `curl`, use `--data-binary` to ensure the payload is transmitted intact.

Run imports serially and schedule them during a maintenance window if the changes are significant to reduce the risk of conflicts.

Concurrency and locking
Mosaic does not currently provide a built-in locking mechanism. Avoid parallel imports for the same tenant and handle locking in your CI/CD pipeline until a service-level lock is introduced in future releases. If you call import while another import is in progress for that tenant, the API returns **409 Conflict** with a message that an import is already in progress; retry after the current import completes.

In addition to the standard import, the Version Management Service provides a [force import API](/openapi/version-management/version-management.openapi/other/versioncontroller_forceimport).

### Force import: risk and caveats

Force import should be a **last resort**. It **skips alias validation only**.
**Database version compatibility and conversion checks still run**, and the **bundle’s structural integrity is enforced**. If database versions are incompatible, force import will fail.

Use cases are rare, for example:

- Recovering from a failed import where alias validation blocks a retry.
- Aligning environments when you intentionally do not provision all aliases in the target tenant (accepting the risks).


Risks include:

- Missing or unresolved aliases will not be detected and can cause runtime errors in journeys.
- The full tenant configuration is overwritten; use `failureRollBack=true` if you want the system to revert the tenant to its state before the import when the import fails or only partially completes.


**Recommendation:** Always run [version validation API](/openapi/version-management/version-management.openapi/other/versioncontroller_validate) and [import API](/openapi/version-management/version-management.openapi/other/versioncontroller_import) first. Use force import only if you fully accept the risks, and ideally under guidance from Transmit Security support.

After a successful import, **run a full regression in the target tenant** to verify that all journeys, configurations, and integrations behave as expected.

## Audit Logging

All import and export operations are recorded in the **Admin User Activity Log** for traceability and troubleshooting.
Logged details include:

- Action type (export, import, validation) and related metadata
- Timestamp


Sensitive data such as tokens or secrets are never stored in plain text; they are redacted or fingerprinted in logs.