Add a Kubernetes cluster
Sidebar: Testing → K8s Posture → Add cluster
apPosture audits a running cluster for security misconfigurations. To do that it needs a snapshot of the cluster's objects (pods, deployments, RBAC, network policies, nodes, admission webhooks, ...). There are two ways to give it that snapshot.
Two connection modes
| Mode | How it works | Use it when |
|---|---|---|
| External | apPosture reads the cluster directly - via a kubeconfig / the API server, or an uploaded dump. apPosture reaches out to the cluster. | Quick, one-off audits, or a lab cluster you can expose to apPosture. |
| Agent (in-cluster) | A read-only CronJob runs inside the cluster and posts the snapshot back to apPosture every 6 hours. No inbound access to the cluster is required. | Production, air-gapped or firewalled clusters - the recommended, most secure model. |
The rest of this page covers the Agent mode, which is what the Add Kubernetes cluster → Agent (in-cluster) screen sets up.
What is the apt_ token?
The apt_… value the screen asks for is an apPosture Personal / Service Access
Token - a bearer credential. The in-cluster agent uses it to authenticate when it
POSTs the cluster snapshot to apPosture; the /k8s-posture/scan endpoint accepts an
apt_ token in the Authorization: Bearer … header.
Where to get it
- In apPosture, open the top-right account menu → Account & security.
- Go to the API & service tokens section and create a new token.
- Give it a name (e.g.
k8s-agent-<cluster>) and a scope. For the agent a token that can post the snapshot is required, so use a full (*) or write-capable service token - a read-only token cannot POST. - The plaintext token (
apt_…) is shown exactly once, at creation. Copy it now - apPosture only stores a hash and can never show it again. If you lose it, revoke it and create a new one.
You can paste the token into the API token field on the Add-cluster screen so the commands below come pre-filled, then click Generate manifest. The token is never written into the YAML - only into a Kubernetes Secret (see below).
Set up the agent (step by step)
1. Create the credential as a Secret
Run this in the target cluster. The token lives in a Secret, not in the manifest, so the YAML is safe to commit to git:
kubectl create namespace apposture
kubectl -n apposture create secret generic apposture-agent \
--from-literal=token='<your apt_ token>'
2. Apply the agent manifest
kubectl apply -f agent.yaml
3. Wait for the first run
The cluster appears in apPosture after the agent's first successful run. It runs every 6 hours; to see results immediately you can trigger it once by hand:
kubectl -n apposture create job --from=cronjob/apposture-posture apposture-posture-now
What the manifest actually deploys
Everything the agent creates is read-only and hardened:
- Namespace
apposture. - ServiceAccount
apposture-scanner. - ClusterRole
apposture-readonly+ binding -get/listonly, on exactly the resources the dump queries (pods, deployments, statefulsets, daemonsets, cronjobs, jobs, roles/clusterroles, rolebindings/clusterrolebindings, networkpolicies, namespaces, serviceaccounts, services, ingresses, nodes, and the validating / mutating admission webhooks). - CronJob
apposture-posture(schedule: "0 */6 * * *") runningbitnami/kubectlas a non-root user, with a read-only root filesystem and all capabilities dropped. Itkubectl get … -A -o jsondumps the cluster andcurls the result tohttps://aspm.apposture.com/api/v1/k8s-posture/scanwithAuthorization: Bearer.
Why it is safe
- No inbound access. The cluster only makes an outbound HTTPS POST; apPosture never connects to your API server.
- The token is never in the YAML. A literal in a PodSpec is readable by anyone with
get cronjob, shows up inkubectl describeand inpsinside the container, and lands in git the moment the file is committed. It is mounted from the Secret viasecretKeyRefinstead, so the manifest carries no credential. - Read-only, and it never reads Secret values. The ServiceAccount can only
get/listobject metadata - it cannot read the contents of your Secrets. A hardcoded credential is only ever detected by reading the PodSpec that references it, not by reading Secret values. - Least privilege that fails closed. Every resource in the ClusterRole is one the
agent actually queries; the dump runs under
set -e, so a missing grant aborts the run rather than silently skipping data.
Troubleshooting
- Cluster never appears. Check the Job logs:
kubectl -n apposture logs job/<apposture-posture-…>. A403there means the token scope is too narrow (use a write-capable service token). An RBACForbiddenon a resource means the ClusterRole is missing a grant - re-apply the latest manifest. curl: (22) … 401- the token is wrong or revoked. Recreate the Secret with a freshapt_token.- Egress blocked - the cluster must be able to reach
https://aspm.apposture.com(or your self-hosted apPosture URL) on 443.