Tekton is a Kubernetes-native CI/CD framework. Unlike Jenkins or GitHub Actions, Tekton runs every pipeline step as a Kubernetes pod. This means your CI/CD security model inherits Kubernetes security — for better and for worse. You get pod-level isolation and RBAC, but you also inherit the complexity of Kubernetes security configuration.
This guide covers how to run Tekton securely, leveraging Kubernetes primitives alongside Tekton-specific features like Tekton Chains.
Tekton's Execution Model
Understanding Tekton's execution model is essential for securing it:
- A Pipeline is a series of Tasks.
- Each Task runs as a Pod with one container per Step.
- Tasks share data via Workspaces (PersistentVolumeClaims or emptyDir volumes).
- PipelineRuns and TaskRuns are the runtime instances.
Every security boundary in Tekton maps to a Kubernetes primitive. Pod security, RBAC, network policies, and resource quotas all apply directly.
Service Account Isolation
Every TaskRun runs under a Kubernetes service account. The default service account in most namespaces has no useful permissions — but many Tekton tutorials tell you to add permissions to default. Do not do this.
Create dedicated service accounts for each pipeline:
apiVersion: v1
kind: ServiceAccount
metadata:
name: build-pipeline-sa
namespace: ci
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: build-pipeline-role
namespace: ci
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
resourceNames: ["registry-credentials"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: build-pipeline-binding
namespace: ci
subjects:
- kind: ServiceAccount
name: build-pipeline-sa
roleRef:
kind: Role
name: build-pipeline-role
apiGroup: rbac.authorization.k8s.io
Note the resourceNames restriction on secrets — the service account can only read the specific secret it needs, not all secrets in the namespace.
Tekton Chains for Supply Chain Security
Tekton Chains is a controller that automatically signs TaskRun results and generates attestations. It is the most important security feature in the Tekton ecosystem.
# Install Tekton Chains
kubectl apply -f https://storage.googleapis.com/tekton-releases/chains/latest/release.yaml
# Configure signing
kubectl patch configmap chains-config -n tekton-chains \
-p='{"data":{"artifacts.taskrun.format":"in-toto","artifacts.taskrun.storage":"oci","artifacts.oci.storage":"oci","transparency.enabled":"true"}}'
With Chains configured:
- Your build task produces a container image.
- Chains automatically generates a SLSA provenance attestation describing what was built, from what source, and by what pipeline.
- Chains signs the attestation with a cryptographic key (Cosign, KMS, or PKCS#11).
- The signed attestation is stored alongside the image in the OCI registry.
Consumers can verify the attestation before deploying the image, closing the supply chain trust gap.
Workspace Security
Tekton workspaces share data between tasks. The security implications depend on the workspace type:
- emptyDir: Ephemeral, exists only for the TaskRun. Secure by default but lost after the task completes.
- PersistentVolumeClaim: Persistent across pipeline runs. Data from previous runs may be accessible. Clean workspaces explicitly.
- Secret/ConfigMap: Read-only, good for injecting credentials.
workspaces:
- name: shared-data
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Use volumeClaimTemplate instead of pre-provisioned PVCs. Templates create a fresh PVC per PipelineRun, preventing data leakage between runs.
For sensitive workspaces, consider adding an init step that wipes the volume before use:
steps:
- name: clean-workspace
image: busybox
command: ['sh', '-c', 'rm -rf /workspace/source/*']
Pod Security
Apply Pod Security Standards to the namespace where Tekton runs pipelines:
apiVersion: v1
kind: Namespace
metadata:
name: ci
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/warn: restricted
The restricted profile prevents containers from running as root, using host networking, or mounting host paths. Some build tools require root — for those, use the baseline profile and document the exception.
For container image builds specifically, use rootless build tools:
- Kaniko: Builds container images without Docker daemon, runs as non-root.
- Buildah: Supports rootless builds with user namespaces.
- ko: Builds Go container images without Docker.
steps:
- name: build-image
image: gcr.io/kaniko-project/executor:latest
command:
- /kaniko/executor
args:
- --dockerfile=Dockerfile
- --context=/workspace/source
- --destination=registry.example.com/app:$(params.tag)
securityContext:
runAsNonRoot: true
Network Policies for Build Namespaces
CI/CD namespaces should have restricted network access:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: ci-pipeline-policy
namespace: ci
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to: []
ports:
- port: 443
protocol: TCP
- to:
- namespaceSelector:
matchLabels:
name: tekton-pipelines
ports:
- port: 8080
protocol: TCP
Allow outbound HTTPS for pulling dependencies and pushing artifacts. Allow communication with the Tekton controller namespace. Block everything else.
Task Verification
Tekton supports verifying task definitions using trusted resources:
apiVersion: tekton.dev/v1
kind: VerificationPolicy
metadata:
name: trusted-tasks
namespace: ci
spec:
resources:
- pattern: "https://github.com/tektoncd/catalog//task/*"
authorities:
- name: tekton-catalog-signer
key:
data: |
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
With verification policies, Tekton rejects tasks that are not signed by a trusted authority. This prevents an attacker from modifying task definitions to inject malicious steps.
Resource Quotas
Prevent denial-of-service by limiting pipeline resource consumption:
apiVersion: v1
kind: ResourceQuota
metadata:
name: ci-quota
namespace: ci
spec:
hard:
requests.cpu: "8"
requests.memory: 16Gi
limits.cpu: "16"
limits.memory: 32Gi
pods: "20"
persistentvolumeclaims: "10"
Without quotas, a misconfigured pipeline (or a malicious one) can consume all cluster resources.
Audit and Observability
Tekton stores PipelineRun and TaskRun results as Kubernetes resources. Export them for analysis:
- Use the Tekton Results API for long-term storage of pipeline execution data.
- Forward Tekton controller logs to your SIEM.
- Monitor for failed signature verifications, unusual task execution patterns, and access to sensitive workspaces.
- Track which service accounts are executing which tasks — deviations from normal patterns may indicate compromise.
How Safeguard.sh Helps
Safeguard.sh integrates with Tekton Chains attestations to provide end-to-end supply chain visibility. It ingests SLSA provenance data from your Tekton pipelines, verifies signatures, and correlates build attestations with SBOM data and vulnerability scans. When a vulnerability is discovered in a dependency, Safeguard.sh traces the impact from the affected package through every Tekton pipeline that built images containing it, down to every cluster where those images are running.