Skip to content
kix /docs
Install the CLI

How-to guide Platform capabilities

Use externally managed secrets

Reference a Secret owned by a secret manager, controller, or cluster operator and validate its keys before a workload starts.

Use scope.mkSecretRef when another system creates the Kubernetes Secret. Kix does not render or update the Secret data, but it validates the keys your package expects and waits for them before applying dependent resources.

This guide assumes the external system creates the Secret in the workload’s namespace.

Add a reference to the package’s returned parts and list every key the package will consume:

how-to/platform/external-secret-app.nix
credentials = scope.mkSecretRef {
name = "billing-api-credentials";
keys = [ "api-key" ];
};

View source on GitHub ↗

The example expects Secret/billing-api-credentials in the package namespace. scope.mkSecretRef emits an import marker rather than a Secret manifest.

Keep the reference in the build function’s returned attrset, as shown by the credentials part above. A reference used only in a let binding is not collected into the cluster artifact.

Use the same out helpers available on a Kix-managed Secret:

how-to/platform/external-secret-app.nix
deployment = scope.mkDeployment {
name = scope.instanceName;
spec = {
replicas = 1;
selector.matchLabels = scope.selectorLabels;
template.spec.containers = [
{
name = "app";
image = "busybox:1.36";
command = [ "sh" "-c" "sleep 3600" ];
env = self.credentials.out.mkEnv {
BILLING_API_KEY = "api-key";
};
}
];
};
};

View source on GitHub ↗

out.mkEnv validates api-key during evaluation and adds the dependency edge from the Deployment to the import marker.

When the package only mounts the whole Secret or loads it with envFrom, and no pod reads one of its keys by name, write keys = [ ];. The deploy then checks only that the Secret exists. A pod that reads a key by name, through secretKeyRef, a volume’s items, or a subPath, fails the cluster build (cross-resource check 22) unless the ref lists that key, so the deploy can check the live Secret holds it.

Evaluate the cluster before connecting to Kubernetes:

kix-examples/
❱ kix check how-to-platform-secrets
 TOOL       RESULT  DETAILS                       
 eval       pass    13 manifests evaluated        
 scorecard  pass    0 errors, 17 warnings, 2 info

Inspect the graph when you need to confirm the deploy ordering:

kix-examples/ offline capture
❱ kix graph how-to-platform-secrets --format tree
Show outputHide output · 40 lines
CustomResourceDefinition/activations.kix.run
└── Activation/how-to-platform-secrets-i4al76srsrdk
CustomResourceDefinition/packageinstances.kix.run
├── PackageInstance/secret-ref-external-example-billing-api-credentials@secret-examples (import)
│   └── Deployment/external-example@secret-examples
│       └── PackageInstance/external-example@secret-examples
│           └── Activation/how-to-platform-secrets-i4al76srsrdk
├── PackageInstance/managed-example@secret-examples
│   └── Activation/how-to-platform-secrets-i4al76srsrdk
├── PackageInstance/external-example@secret-examples
│   └── Activation/how-to-platform-secrets-i4al76srsrdk
├── PackageInstance/platform-storage@kube-system (import)
│   └── Activation/how-to-platform-secrets-i4al76srsrdk
└── PackageInstance/platform-dns@kube-system (import)
    └── Activation/how-to-platform-secrets-i4al76srsrdk
Namespace/kube-system
├── PackageInstance/platform-storage@kube-system (import)
│   └── Activation/how-to-platform-secrets-i4al76srsrdk
└── PackageInstance/platform-dns@kube-system (import)
    └── Activation/how-to-platform-secrets-i4al76srsrdk
Namespace/secret-examples
├── Secret/managed-example-credentials@secret-examples
│   └── Deployment/managed-example@secret-examples
│       └── PackageInstance/managed-example@secret-examples
│           └── Activation/how-to-platform-secrets-i4al76srsrdk
├── PackageInstance/secret-ref-external-example-billing-api-credentials@secret-examples (import)
│   └── Deployment/external-example@secret-examples
│       └── PackageInstance/external-example@secret-examples
│           └── Activation/how-to-platform-secrets-i4al76srsrdk
├── PackageInstance/managed-example@secret-examples
│   └── Activation/how-to-platform-secrets-i4al76srsrdk
├── PackageInstance/external-example@secret-examples
│   └── Activation/how-to-platform-secrets-i4al76srsrdk
├── Deployment/managed-example@secret-examples
│   └── PackageInstance/managed-example@secret-examples
│       └── Activation/how-to-platform-secrets-i4al76srsrdk
└── Deployment/external-example@secret-examples
    └── PackageInstance/external-example@secret-examples
        └── Activation/how-to-platform-secrets-i4al76srsrdk
13 resources, 22 dependencies

The secret-ref-external-example-billing-api-credentials import appears before Deployment/external-example.

Confirm that the provider has created the Secret in the expected namespace:

❱ kubectl get secret billing-api-credentials -n secret-examples

During kix deploy, Kix checks that the Secret exists and contains the declared keys before applying the dependent Deployment. A missing Secret or key fails that deploy wave rather than starting the workload with an invalid reference.