The chart never embeds secrets in templated objects — it always
references a Secret resource by name.

What’s secret

Value Where Sensitivity
Netskope API token (enrollment.api.authMode=token) Secret npa-api-token key api-token High — full publisher admin scope
OAuth2 client credentials (enrollment.api.authMode=oauth2) Secret npa-api-oauth keys client-id and client-secret High — can mint API access tokens
Registration token (mode: token) Secret you create, or --set value Medium — single-use, short-lived
Image pull credentials Secret of type kubernetes.io/dockerconfigjson Medium

Creating secrets safely

1
2
3
kubectl create secret generic npa-api-token \
--namespace npa-publisher \
--from-literal=api-token='paste-here'

For OAuth2 API authentication:

1
2
3
4
kubectl create secret generic npa-api-oauth \
--namespace npa-publisher \
--from-literal=client-id='paste-client-id-here' \
--from-literal=client-secret='paste-client-secret-here'

⚠️ Do not pass secrets to helm install --set .... Helm logs the
rendered manifest with values visible to anyone with release-history
access. Use existingSecret instead.

GitOps with sealed/encrypted secrets

The chart references existing secrets by name, so anything that
produces a regular Secret resource works:

  • Sealed Secrets (bitnami): seal a Secret, commit the SealedSecret,
    controller decrypts it in-cluster.
  • External Secrets Operator (ESO): create an ExternalSecret
    pointing at Vault / AWS Secrets Manager / Azure Key Vault.
  • SOPS + helmfile: sops-encrypt the values file, helmfile decrypts
    at deploy time — but store only the existingSecret: <name>
    reference in values
    , never the token itself.

Rotation

See rotate-token.

Auditing

  • The chart’s ServiceAccount doesn’t have permission to read the API-token
    Secret. The kubelet injects it as a volume into the init container only.
  • Audit logs (audit.k8s.io/v1) will record any human/manual get
    against the Secret. Watch for those if you have access control concerns.