Shipping the PostQ Kubernetes agent
TLS Secrets, Ingress, cert-manager, and mesh mTLS — all in one Helm install.
We just cut v0.2.0of the PostQ Kubernetes agent. It’s shipped two ways — as a multi-arch container image and as a Helm chart, both hosted as OCI artifacts in GitHub Container Registry:
helm install postq-agent oci://ghcr.io/postqdev/charts/postq-agent \
--version 0.2.0 \
--namespace postq --create-namespace \
--set apiKey=$POSTQ_API_KEY \
--set orgId=$POSTQ_ORG_ID \
--set clusterName=prod-east-1That one command gives you a read-only, non-root, distroless pod running on a CronJob inside your cluster. It walks every namespace you let it see, finds every quantum-vulnerable algorithm hiding in there, and ships the findings back to your PostQ dashboard over a single outbound HTTPS connection. No inbound network. No sidecars. No webhook controllers.
Why an in-cluster agent?
The PostQ CLI can already point at any TLS endpoint and tell you what’s broken. The web scanner can do the same from the cloud. So why a third surface?
Three things kept coming up in customer calls:
- “Half our certs aren’t on the public internet.” Internal services. Service-to-service mTLS. Nothing a SaaS scanner can reach without a corporate firewall change nobody wants to sign.
- “We rotate certs every 24 hours via cert-manager.” A point-in-time scan is borderline useless when your cert inventory churns daily. You need a recurring sweep that catches a regression within the hour.
- “Show me the asset, not just the algorithm.” Engineers don’t want to hear “you have RSA-2048 somewhere” — they want to hear “Secret
prod/api-tlsreferenced by Ingressprod/api-publicuses a 2048-bit RSA key, expires in 17 days, and is signed by thiscert-manager Issuer.”
An in-cluster agent is the right answer to all three. It runs where the truth lives.
What v0.2 actually scans
The agent is a small Go binary that uses client-go and the in-cluster ServiceAccount. Per scan, it walks:
kubernetes.io/tlsSecrets — parses the leaf cert and the private key, extracts the public-key algorithm and bit length, classifies risk against the current PQC guidance.- Ingresses— cross-references TLS-enabled ingresses with the secrets they reference, so a vulnerable cert that’s actually serving traffic gets bumped a severity level.
- ConfigMaps— yes, people still embed PEM blocks in ConfigMaps. We find them.
- cert-manager Certificates / Issuers / ClusterIssuers — if the chart is installed, the agent reads the desired spec, not just the rendered Secret, so you see vulnerabilities before they get rotated into the cluster.
- Istio PeerAuthentication / DestinationRule / Gateway and Linkerd MeshTLSAuthentication — mTLS posture for service meshes. PERMISSIVE mode is loud today; it’ll be louder once Q-day is on the calendar.
Each finding lands in the dashboard with the full Kubernetes coordinates — namespace, kind, name, the cert SANs, the algorithm, the bit length, and a remediation suggestion that points at the relevant NIST FIPS standard.
The chart, in 60 seconds
The two install modes most people will use:
helm install postq-agent oci://ghcr.io/postqdev/charts/postq-agent \
--version 0.2.0 \
--namespace postq --create-namespace \
--set apiKey=$POSTQ_API_KEY \
--set orgId=$POSTQ_ORG_ID \
--set clusterName=prod-east-1# Pre-create the Secret however your org likes
kubectl -n postq create secret generic postq-agent-key \
--from-literal=POSTQ_API_KEY=$POSTQ_API_KEY
helm install postq-agent oci://ghcr.io/postqdev/charts/postq-agent \
--version 0.2.0 \
--namespace postq \
--set existingSecret.name=postq-agent-key \
--set orgId=$POSTQ_ORG_ID \
--set clusterName=prod-east-1Defaults that we’d like other people to copy: pod runs as UID 65532, read-only root filesystem, all capabilities dropped, seccompProfile: RuntimeDefault. Resource requests sit at 50m / 64Mi — you won’t see this thing on a noisy-neighbor report. The CronJob defaults to hourly; flip oneShot=true to swap it for a one-off Job for a smoke test.
How we ship it
The whole release pipeline is two GitHub Actions workflows. Tag a commit postq-agent-v0.2.0, and:
- Image:
docker buildxbuilds linux/amd64 and linux/arm64 from the distroless Dockerfile and pushes toghcr.io/postqdev/postq-agent:0.2.0(and:latest). - Chart:
helm lintandhelm templaterun on every PR (in default andexistingSecretmode), then on tag wehelm packageandhelm pushthe resulting tarball tooci://ghcr.io/postqdev/charts. A guard step refuses to publish ifChart.yamland the tag disagree.
Both workflows authenticate with GITHUB_TOKEN (with a PAT fallback for cross-org pushes). No third-party services in the supply chain.
Where this fits
The agent is the third pillar of PostQ’s discovery story:
- Web— quick spot-checks against any public hostname.
- CLI— CI gates and scripted scans across an inventory.
- Kubernetes agent — continuous, in-cluster inventory with full asset context.
They feed the same dashboard, so a finding from the agent deduplicates against a finding from the CLI against a finding from the web scanner. One asset, one verdict, one remediation thread.
What’s next
- Optional admission webhook that can block a vulnerable Secret or Ingress at apply time, not just report it after the fact.
- cert-manager Issuer policy hints — suggesting a hybrid ML-DSA + ECDSA profile for issuers that are eligible.
- SBOM + Cosign signatures on both the image and the chart.
- Helm chart published to Artifact Hub for one-click discovery.
Try it, file an issue, tell us what you find. The agent is designed to make “how much quantum-vulnerable crypto is in my cluster?” a question with a clear, dated answer instead of a shrug.
Read the docs: postq.dev/docs. Ship a finding to the dashboard: app.postq.dev. Source for the agent + chart lives at PostQDev/postq-scanner-tool.