Watches Kubernetes deployments and reports them to Postman's Service Inventory.
142
The Postman Kubernetes Listener Service watches Kubernetes deployments in your cluster and automatically reports them to Postman's Service Inventory. This gives your team real-time visibility into what's deployed, where, and which version.
The chart supports three ways to provide the Postman API key. Pick one based on how you already manage secrets:
| If you... | Use |
|---|---|
| Want the simplest install and manage secrets manually | Existing K8s secret (recommended) |
| Already use External Secrets Operator with Vault / AWS Secrets Manager / GCP Secret Manager | External secret |
| Are running a throwaway eval and accept the key in release state | Inline --set (not recommended) |
The chart is published as an OCI artifact on Docker Hub at
oci://registry-1.docker.io/postman/postman-kubernetes-listener. Pin a specific
version on every install with --version <x.y.z>.
Discover the available chart versions:
helm show chart oci://registry-1.docker.io/postman/postman-kubernetes-listener
The recommended way to authenticate with the Postman servers is using an API key stored in a Kubernetes secret:
kubectl create secret generic postman-api-key \
--from-literal=api-key=YOUR_POSTMAN_API_KEY
helm install k8s-listener \
oci://registry-1.docker.io/postman/postman-kubernetes-listener \
--version <chart-version> \
--set postman.apiKeyExistingSecret=postman-api-key \
--set listener.clusterName=my-cluster \
--set listener.region=us-east-1 \
--set listener.environmentName=production
Tip — avoid leaking the key into shell history or CI logs
The command above embeds the key on the command line, so it gets recorded in
~/.zsh_history/~/.bash_historyand in any CI step that echoes commands. Two safer patterns:Pipe the value via stdin (key never appears on a command line):
read -rs POSTMAN_API_KEY # prompts without echoing printf '%s' "$POSTMAN_API_KEY" | \ kubectl create secret generic postman-api-key \ --from-file=api-key=/dev/stdinOr reference a pre-set environment variable (shell history records the variable name, not the value — and most CI systems mask declared secret env vars in logs):
kubectl create secret generic postman-api-key \ --from-literal=api-key="$POSTMAN_API_KEY"Use
printf '%s'rather thanechoor a here-string (<<<) when piping — kubectl stores the file content verbatim, and a trailing newline becomes part of the secret value.
If you already run External Secrets Operator (ESO), the chart can create an ExternalSecret that syncs the API key from your remote secret store (Vault, AWS Secrets Manager, GCP Secret Manager, etc.).
Prerequisites and pitfalls:
ClusterSecretStore (cluster-scoped). Set its name via global.externalSecretStore.value — the chart reads property: value from the remote reference.<baseName>-api-key with key api-key, refreshed every 10 minutes.helm install k8s-listener \
oci://registry-1.docker.io/postman/postman-kubernetes-listener \
--version <chart-version> \
--set postman.apiKeyExternalSecret=secret/data/postman/api-key \
--set global.externalSecretStore=my-cluster-secret-store \
--set listener.clusterName=my-cluster \
--set listener.region=us-east-1 \
--set listener.environmentName=production
WARNING: Passing the API key as a plain Helm value could lead to the key being leaked via shell history, CI logs, or in Kubernetes release state, so is NOT RECOMMENDED.
helm install k8s-listener \
oci://registry-1.docker.io/postman/postman-kubernetes-listener \
--version <chart-version> \
--set postman.apiKey=YOUR_POSTMAN_API_KEY \
--set listener.clusterName=my-cluster \
--set listener.region=us-east-1 \
--set listener.environmentName=production
All configuration is done through Helm values. You can pass them with --set, or create a values.yaml file and use -f:
helm install k8s-listener \
oci://registry-1.docker.io/postman/postman-kubernetes-listener \
--version <chart-version> \
-f my-values.yaml
| Parameter | Description | Default |
|---|---|---|
postman.apiKey | Postman API key for authentication (inline — not recommended) | "" |
postman.apiKeyExistingSecret | Name of an existing K8s secret containing the API key in a key named api-key | "" |
postman.apiKeyExternalSecret | Remote key path in your external secret store (the remote secret must have a value field) | "" |
postman.apiHttpLogLevel | Logging level for outbound Postman API HTTP calls (set to TRACE to debug connectivity) | WARN |
Exactly one of apiKey, apiKeyExistingSecret, or apiKeyExternalSecret should be set.
| Parameter | Description | Default |
|---|---|---|
listener.clusterName | Unique cluster identifier. Defaults to the K8S_CLUSTER_ID pod env var if unset. | "" |
listener.region | Cloud region identifier. Defaults to the AWS_DEFAULT_REGION pod env var if unset. | "" |
listener.environmentName | Deployment environment name. Defaults to the RESOURCE_ENV pod env var if unset. | "" |
listener.namespaces | Comma-separated namespaces to watch (empty = all) | "" |
listener.overrides | Free-form env-var overrides — see Listener overrides | {} |
| Parameter | Description | Default |
|---|---|---|
global.externalSecretStore | ClusterSecretStore name (required if apiKeyExternalSecret is set) | "" |
| Parameter | Description | Default |
|---|---|---|
resources.requests.memory | Memory request | 256Mi |
resources.requests.cpu | CPU request | 100m |
resources.limits.memory | Memory limit | 512Mi |
resources.limits.cpu | CPU limit | 500m |
The chart's defaults satisfy the Pod Security Standards "restricted" profile (non-root, read-only root filesystem, all capabilities dropped, no privilege escalation, RuntimeDefault seccomp). Override only if your cluster needs different settings.
| Parameter | Description |
|---|---|
podSecurityContext | Pod-level security context. Default: non-root UID 10001, fsGroup 10001, RuntimeDefault seccomp. |
securityContext | Container-level security context. Default: non-root UID 10001, read-only root FS, all capabilities dropped, no privilege escalation. |
| Parameter | Description | Default |
|---|---|---|
baseName | Base name used for resource naming | postman-kubernetes-listener |
image.repository | Docker image repository | postman/postman-kubernetes-listener |
image.tag | Image tag (defaults to chart AppVersion) | "" |
image.pullPolicy | Image pull policy | IfNotPresent |
image.pullSecrets | Image pull secrets | [] |
env.defaults.vars | Additional environment variables | {} |
podAnnotations | Additional pod annotations | {} |
nodeSelector | Node selector | {} |
tolerations | Tolerations | [] |
affinity | Affinity rules | {} |
listener.overrides is a free-form map of environment variables passed through to the container. Use it to tune listener behaviors that aren't exposed as first-class Helm values.
| Env var | Purpose | Default |
|---|---|---|
LISTENER_LABEL_SELECTOR | Standard Kubernetes label selector applied when watching Deployments — only matching Deployments are reported to Postman. | app.postman.io/api-catalog |
LISTENER_VERSION_LABEL_NAME | Name of the label on a Deployment that the listener reads to extract the deployed application's version. | app.kubernetes.io/version |
LISTENER_LABEL_PATTERN | Regex applied to label keys and annotation keys — only matching keys are forwarded to Postman as metadata. | app.postman.io/.* |
Example:
listener:
overrides:
LISTENER_LABEL_SELECTOR: app.postman.io/k8s-app
LISTENER_VERSION_LABEL_NAME: app.kubernetes.io/version
LISTENER_LABEL_PATTERN: "^app\\..*"
To watch a specific list of namespaces, use the dedicated listener.namespaces value rather than setting LISTENER_NAMESPACES here — the chart already wires the dedicated value into the container.
Check that the pod is running:
kubectl get pods -l app.kubernetes.io/name=postman-kubernetes-listener
View logs:
kubectl logs -l app.kubernetes.io/name=postman-kubernetes-listener -f
Check the health endpoint. The chart does not ship a Service, so port-forward directly to the pod:
POD=$(kubectl get pod -l app.kubernetes.io/name=postman-kubernetes-listener \
-o jsonpath='{.items[0].metadata.name}')
kubectl port-forward "pod/$POD" 8081:8081
curl http://localhost:8081/actuator/health
Every public release publishes the following supply-chain artifacts to the OCI registry alongside the image:
cosign verify \
--certificate-identity-regexp "https://github.com/postman-eng/postman-kubernetes-listener-pub/.+" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
index.docker.io/postman/postman-kubernetes-listener:<tag>
Both the SBOM and the build provenance attestation can be verified with the GitHub CLI:
gh attestation verify \
oci://index.docker.io/postman/postman-kubernetes-listener:<tag> \
--owner postman-eng
To download and inspect the SBOM itself, use cosign download attestation or oras discover.
The Postman Kubernetes Listener Service connects to the Kubernetes API server using its service account credentials and opens a watch stream on Deployment resources. When a deployment is created, updated, or deleted, the service extracts relevant metadata (name, namespace, labels, version, replica count) and reports it to Postman's Service Inventory API.
Namespace filters can be used to control which deployments are tracked. Only deployments in namespaces matching your configured listener.namespaces
will be reported.
| Port | Purpose |
|---|---|
| 8081 | Spring Actuator management (health, readiness, metrics) |
The service requires read-only access to Deployment resources:
appsdeploymentsget, list, watchhelm upgrade k8s-listener \
oci://registry-1.docker.io/postman/postman-kubernetes-listener \
--version <chart-version> \
--reuse-values
helm uninstall k8s-listener
Pod CrashLoopBackOff with auth error — The API key is missing or the secret has the wrong key name. The chart expects the secret to have a key named api-key. Verify with kubectl get secret <name> -o yaml.
Pod can't list deployments — The ClusterRole/Binding may not be applied, or another policy is blocking it. Verify with:
kubectl auth can-i list deployments \
--as=system:serviceaccount:<namespace>:<service-account>
Nothing showing up in Service Inventory — Either your listener.namespaces filter excludes the workloads you expect to see, or your Deployments don't match the default LISTENER_LABEL_SELECTOR (app.postman.io/api-catalog). Set postman.apiHttpLogLevel=TRACE to log outbound calls and confirm what's being sent.
Content type
Helm
Digest
sha256:605513b0e…
Size
3.2 kB
Last updated
about 2 months ago
helm pull oci://registry-1.docker.io/postman/postman-kubernetes-listener --version 1.0.0-helm