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

# Migrating to chainloop-ee chart

> How to migrate from OSS+Platform to unified EE chart

This guide helps you migrate from:

* the [Platform chart](/guides/deployment/platform)
* the [OSS chart](/guides/deployment/oss)

to the combined Enterprise chart:

* Chainloop [Enterprise edition](/guides/deployment/chainloop-ee)

## What Changed

* `chainloop-ee` combines both distributions in one chart.
* Some configuration is no longer required as it's handled by the chart itself
* Most Platform keys under `frontend`, `backend`, `global`, and `nats` remain in the same sections.
* Most OSS keys under `controlplane` and `cas` remain in the same sections.
* Database configuration is centralized in top-level `chainloopDatabase` and `platformDatabase`.
* Development dependencies (`vault`, `dex`, `postgresql`) are now wired for the combined install path.

### Top-Level Ingress Defaults

`chainloop-ee` introduces a top-level `ingress` block that works as a global fallback for component ingress settings.

* Supported keys: `ingress.enabled`, `ingress.hostname`, `ingress.ingressClassName`, `ingress.annotations`, `ingress.tls`.
* Precedence: component-specific values (`frontend.ingress.*`, `backend.ingress.*`, `controlplane.ingress.*`, `cas.ingress.*`, and `*.ingressAPI.*`) override top-level values when both are set.
* Rendering behavior: ingress resources render when either the component ingress is enabled or top-level `ingress.enabled` is true.
* Hostname derivation from top-level `ingress.hostname`:
  * frontend: `app.<hostname>`
  * backend: `app-api.<hostname>`
  * controlplane: `cp.<hostname>`
  * controlplane API: `cp-api.<hostname>`
  * cas: `cas.<hostname>`
  * cas API: `cas-api.<hostname>`
* `ingress.annotations` and `ingress.tls` are reused as shared defaults (for example, cert-manager annotations and HTTPS defaults).

## Migration Checklist

<Tip>
  Make sure to get familiar with [Removed Keys](/guides/deployment/guides/migration-guide#removed-keys) section before you start copying your values.
</Tip>

1. Start from [Enterprise edition](/guides/deployment/chainloop-ee) chart values.yaml. Refer to README.md for more details about configuration options.
2. Copy your Platform customizations (`frontend`, `backend`, `nats`) into the same sections.
3. Copy your OSS customizations (`controlplane`, `cas`, `secretsBackend`, `casJWT*`) into the same sections.
4. Apply the key remaps from the tables below.
5. Run `helm template` / `helm upgrade --dry-run` and validate rendered secrets, DB endpoints, and ingress hosts.

## Platform -> `chainloop-ee` Mapping

### Mostly Unchanged Paths

These sections are largely drop-in:

* `global.*`
* `frontend.*`
* `backend.*`
* `nats.*`

### Required Remaps

| Old path (platform)                    | New path (`chainloop-ee`)       | Notes                                                     |
| -------------------------------------- | ------------------------------- | --------------------------------------------------------- |
| `backend.auth.chainloopAuthPassphrase` | `chainloopAuthPassphrase`       | Moved to top-level. Required in non-development installs. |
| `backend.externalChainloopDatabase.*`  | `chainloopDatabase.*`           | Chainloop (control plane) DB connection is now top-level. |
| `backend.externalDatabase.*`           | `platformDatabase.*`            | Platform DB connection is now top-level.                  |
| `frontend.service.port`                | `frontend.service.ports.http`   | Service schema follows chart conventions with `ports`.    |
| `backend.service.port`                 | `backend.service.ports.http`    | Same schema update as frontend.                           |
| `backend.mcpService.port`              | `backend.mcpService.ports.http` | Same schema update for MCP service.                       |
| `frontend.service.targetPort`          | n/a                             | Not exposed in values in the combined chart.              |
| `backend.service.targetPort`           | n/a                             | Not exposed in values in the combined chart.              |
| `backend.mcpService.targetPort`        | n/a                             | Not exposed in values in the combined chart.              |

### Notable Default/Model Changes

* `frontend.service` / `backend.service` / `backend.mcpService` now include additional service fields (`clusterIP`, `nodePorts`, `externalTrafficPolicy`, etc.).
* `frontend` and `backend` include explicit pod/container security context defaults in `chainloop-ee`.
* `ingress.*` at top-level acts as a shared default for all component ingresses.

## OSS -> `chainloop-ee` Mapping

### Mostly Unchanged Paths

These are generally reusable as-is:

* `controlplane.*`
* `cas.*`
* `secretsBackend.*`
* `casJWTPrivateKey`
* `casJWTPublicKey`

### Required Remaps

| Old path (OSS)                             | New path (`chainloop-ee`) | Notes                                                      |
| ------------------------------------------ | ------------------------- | ---------------------------------------------------------- |
| `controlplane.auth.passphrase`             | `chainloopAuthPassphrase` | Moved to top-level. Required in non-development installs.  |
| `controlplane.externalDatabase.*`          | `chainloopDatabase.*`     | DB endpoint/user/database moved to top-level shared model. |
| `controlplane.customCAs` + `cas.customCAs` | `customCAs`               | Unified top-level CA injection list.                       |

## Removed Keys

Use this section as a quick reference for keys that existed in Platform or OSS values but are not present in `chainloop-ee` as the same path.

| Removed key                                           | Replacement / action                                                                               |
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `controlplane.externalDatabase.*`                     | Use `chainloopDatabase.*` (top-level).                                                             |
| `controlplane.customCAs`                              | Use top-level `customCAs`.                                                                         |
| `controlplane.uiDashboardURL`                         | No replacement in values (chart-managed).                                                          |
| `controlplane.ingress.selfSigned`                     | No direct replacement in `chainloop-ee` values.                                                    |
| `controlplane.ingressAPI.selfSigned`                  | No direct replacement in `chainloop-ee` values.                                                    |
| `controlplane.auth.passphrase`                        | Use `chainloopAuthPassphrase` (top-level).                                                         |
| `cas.customCAs`                                       | Use top-level `customCAs`.                                                                         |
| `frontend.service.port`                               | Use `frontend.service.ports.http`.                                                                 |
| `frontend.service.targetPort`                         | No replacement in values (chart-managed).                                                          |
| `backend.auth.chainloopAuthPassphrase`                | Use `chainloopAuthPassphrase` (top-level).                                                         |
| `backend.externalDatabase.*`                          | Use `platformDatabase.*` (top-level).                                                              |
| `backend.externalChainloopDatabase.*`                 | Use `chainloopDatabase.*` (top-level).                                                             |
| `backend.service.port`                                | Use `backend.service.ports.http`.                                                                  |
| `backend.mcpService.port`                             | Use `backend.mcpService.ports.http`.                                                               |
| `backend.service.targetPort`                          | No replacement in values (chart-managed).                                                          |
| `backend.mcpService.targetPort`                       | No replacement in values (chart-managed).                                                          |
| `backend.cas_api`                                     | No direct replacement in `chainloop-ee` values. Backend CAS API wiring is chart-managed.           |
| `backend.cas_api.addr`                                | No direct replacement in `chainloop-ee` values. Backend CAS API wiring is chart-managed.           |
| `backend.cas_api.insecure`                            | No direct replacement in `chainloop-ee` values. Backend CAS API wiring is chart-managed.           |
| `backend.controlplane_api`                            | No direct replacement in `chainloop-ee` values. Backend control plane API wiring is chart-managed. |
| `backend.controlplane_api.addr`                       | No direct replacement in `chainloop-ee` values. Backend control plane API wiring is chart-managed. |
| `backend.controlplane_api.insecure`                   | No direct replacement in `chainloop-ee` values. Backend control plane API wiring is chart-managed. |
| `backend.customCAs`                                   | Use top-level `customCAs`.                                                                         |
| `backend.ingress.selfSigned`                          | No direct replacement in `chainloop-ee` values.                                                    |
| `backend.mcp`                                         | No replacement in values (chart-managed).                                                          |
| `backend.mcp.oauth`                                   | No replacement in values (chart-managed).                                                          |
| `backend.mcp.oauth.enabled`                           | No replacement in values (chart-managed).                                                          |
| `backend.mcp.oauth.authProvider`                      | No replacement in values (chart-managed).                                                          |
| `backend.mcp.oauth.authProvider.clientId`             | No replacement in values (chart-managed).                                                          |
| `backend.mcp.oauth.authProvider.clientSecret`         | No replacement in values (chart-managed).                                                          |
| `backend.mcp.oauth.authProvider.issuerUrl`            | No replacement in values (chart-managed).                                                          |
| `backend.mcpIngress.selfSigned`                       | No replacement in values                                                                           |
| `global.compatibility.openshift.adaptSecurityContext` | No direct replacement in `chainloop-ee` values.                                                    |
| `cas.ingress.selfSigned`                              | No direct replacement in `chainloop-ee` values.                                                    |
| `cas.ingressAPI.selfSigned`                           | No direct replacement in `chainloop-ee` values.                                                    |

## Vault in `chainloop-ee`

`chainloop-ee` vendors the Vault subchart (`chainloop-ee/charts/vault/values.yaml`) and only overrides a small subset at top-level `vault.*`:

* `vault.server.command`
* `vault.server.args`
* `vault.server.config`
* `vault.server.extraVolumes`
* `vault.server.extraVolumeMounts`
* `vault.extraDeploy`

If you previously customized standard Vault chart keys, keep using the same key paths under `vault.*` in `chainloop-ee`.

## Minimal Migrated Values Example

```yaml theme={"dark"}
chainloopAuthPassphrase: "replace-me"

chainloopDatabase:
  host: "chainloop-db"
  port: 5432
  user: "chainloop"
  database: "chainloop"
  password: "replace-me"

platformDatabase:
  host: "platform-db"
  port: 5432
  user: "backenduser"
  database: "backend"
  password: "replace-me"

secretsBackend:
  backend: "vault"
  secretPrefix: "chainloop"
  vault:
    address: https://vault.example.com
    token: "s.1234567890"
casJWTPrivateKey: |-
  -----BEGIN RSA PRIVATE KEY-----
  MIIEpAIBAAKCAQEA
  -----END RSA PRIVATE KEY-----
casJWTPublicKey: |-
  -----BEGIN PUBLIC KEY-----
  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
  -----END PUBLIC KEY-----
controlplane:
  auth:
    oidc:
      url: "replace-me"
      clientID: "replace-me"
      clientSecret: "replace-me"
  keylessSigning:
    enabled: true
    backends:
      - type: fileCA
        fileCA:
          cert: |-
            -----BEGIN CERTIFICATE-----
            MIIEpAIBAAKCAQEA
            -----END CERTIFICATE-----
          key: |-
            -----BEGIN ENCRYPTED RSA PRIVATE KEY-----
            MIIEowIBAAKCAQEA
            -----END ENCRYPTED RSA PRIVATE KEY-----
          keyPass: "replace-me"
        issuer: true
ingress:
  enabled: true
  hostname: "chainloop.example.com"
  ingressClassName: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  tls: true
```

## Validation Steps

* Render manifests:
  * `helm template chainloop-ee ./deployment/chainloop-ee -f <your-values>.yaml`
* Dry-run upgrade:
  * `helm upgrade --install chainloop-ee ./deployment/chainloop-ee -f <your-values>.yaml --dry-run`
* Verify:
  * ingress hosts/TLS per component
  * secretsBackend configuration
  * machineIdentityIssuers and chainloopAuthPassphrase configuration
  * All custom configuration about autoOnboarding, restrictOrgCreation, keylessSigning, etc.
  * casJWTPrivateKey and casJWTPublicKey configuration

## References

* OSS values reference: [chainloop OSS values.yaml](https://github.com/chainloop-dev/chainloop/blob/main/deployment/chainloop/values.yaml)
