Every Tekton TaskRun is a Kubernetes pod running with a service account and whatever secrets that account carries, so the security of a Tekton pipeline is mostly the security of the identities, triggers and definitions that feed those pods. This guide covers the customer side of running Tekton securely: service accounts and credential handling in Tekton Pipelines, EventListener and interceptor configuration in Tekton Triggers, signature verification of remote Tasks and Pipelines with Trusted Resources, and provenance signing with Tekton Chains. It is written for platform engineers and DevSecOps teams who run Tekton directly or through a distribution built on it. For CI/CD controls that apply to every platform, see the CI/CD Security Guide; for deployment through Git, see the GitOps Security Guide.
This is an independent guide from NHI Mgmt Group, based on Tekton's public documentation as of November 2026. It is not sponsored or reviewed by the Tekton project. Product features change, so confirm settings against Tekton's current documentation for the version you run.
Key takeaways
- Never let runs fall back to the default service account. TaskRuns and PipelineRuns without serviceAccountName use default-service-account from config-defaults; set a dedicated, minimal account per pipeline and change the cluster default.
- Scope secrets to the steps that need them. Annotated secrets on a run's service account are available to every step in the Task by default; mount them as volumes into specific steps, or set disable-creds-init and pass credentials through Workspaces.
- Validate every webhook. The GitHub interceptor without secretRef returns continue: true without checking the signature, and an EventListener acts with its service account's rights on every event it accepts.
- Verify remote definitions before they run. Trusted Resources checks the tekton.dev/signature annotation on remote Tasks and Pipelines against a VerificationPolicy; set trusted-resources-verification-no-match-policy to fail once policies cover your sources.
- Sign provenance with a key you manage well. Tekton Chains signs runs and OCI images; prefer a KMS signer or keyless signing over a static key in signing-secrets, and choose the slsa/v1 format for provenance consumers.
How identity and access work in Tekton
Tekton has no separate user database. Users and automation create Tekton custom resources (Task, Pipeline, TaskRun, PipelineRun, EventListener, Trigger and others) through the Kubernetes API, so Kubernetes RBAC decides who can define and start work. The pods those runs create act with the service account named in the run. Four identities matter:
| Identity | Where it is set | What it can do | Customer control |
|---|---|---|---|
| People and automation creating runs | Kubernetes RBAC on tekton.dev resources | Start runs that use any service account they can name in the namespace | Namespace-scoped Roles; separate rights to edit Tasks from rights to start runs |
| Run service account | serviceAccountName on TaskRun or PipelineRun, else default-service-account | Carries Git and registry secrets, and Kubernetes API rights inside step pods | One minimal account per pipeline; no cluster-wide bindings |
| EventListener service account | spec.serviceAccountName (required) | Creates Tekton objects for every accepted event | Bind only the documented Triggers roles; separate accounts per Trigger where needed |
| Chains controller | tekton-chains namespace, signing-secrets or KMS | Signs and stores provenance and image signatures | KMS or keyless signing; restrict read on signing-secrets |
The design point to keep in mind is that anyone who can create a TaskRun in a namespace can choose any service account in that namespace. Keep high-privilege service accounts, such as those holding production registry or deployment credentials, in namespaces where only release automation can create runs. See the Kubernetes Service Account Token Guide for token handling.
Admin roles and privileged access
- Tekton installation namespaces: tekton-pipelines, tekton-pipelines-resolvers and tekton-chains hold the controllers, the feature-flags and config-defaults ConfigMaps and the Chains signing material. Write access to these ConfigMaps changes security behaviour for the whole cluster (for example turning off verification), so treat it as cluster-admin and alert on changes.
- Task and Pipeline authors: whoever can edit a Task controls the code that runs with the run's service account. Store Task and Pipeline definitions in Git with review, resolve them remotely, and sign them for Trusted Resources rather than letting users apply them directly in production namespaces.
- Inline specifications: the disable-inline-spec feature flag (empty by default) accepts a comma-separated list of pipeline, pipelinerun and taskrun to block embedded specs, so runs must reference reviewed definitions.
- Pod security: set set-security-context to true (default false) so Tekton-injected containers get a SecurityContext that lets pods run under the restricted Pod Security Standard, and set-security-context-read-only-root-filesystem where your steps allow it. Use default-pod-template in config-defaults for cluster-wide pod settings, and default-forbidden-env to stop PodTemplates overriding sensitive environment variables.
- Resolvers: the bundles, git, hub and cluster resolvers are enabled by default in resolvers-feature-flags. Turn off any you do not use (for example enable-hub-resolver: false) so runs can only pull definitions from approved sources.
Integrations, API tokens and service accounts
Git and registry credentials in Pipelines
Tekton's authentication documentation describes how a run gets credentials through its service account. Secrets of type kubernetes.io/basic-auth or kubernetes.io/ssh-auth (Git) and kubernetes.io/basic-auth, kubernetes.io/dockercfg or kubernetes.io/dockerconfigjson (registries) must carry annotations beginning tekton.dev/git- or tekton.dev/docker- whose value is the host URL; adding a path makes a credential repository-specific. Before any step runs, Tekton writes these into /tekton/creds and the home directory as ~/.gitconfig, ~/.ssh or ~/.docker/config.json.
| Approach | Configuration | Trade-off |
|---|---|---|
| Built-in credential initialisation | Annotated secrets on the run's service account | Simple; every step in the Task can read the credentials |
| Per-step volume mounts | Mount the secret as a volume into named steps only | Limits exposure to the steps that clone or push |
| Explicit Workspaces | disable-creds-init: "true" in feature-flags; pass secrets as Workspaces | Most explicit; Task authors must wire credentials themselves |
| Short-lived tokens | Fetch tokens at run time from a secrets manager or cloud workload identity | No stored long-lived token; needs integration work |
For SSH, include known_hosts in the secret and set require-git-ssh-secret-known-hosts to true so that runs fail validation rather than accepting any server key on first use. Pulling step images uses imagePullSecrets on the service account, separate from the above. Our recommendation at NHI Mgmt Group is repository-scoped, read-only Git credentials for build pipelines and a separate, push-capable identity only in release pipelines. See the CI/CD Pipeline Identity Security Guide.
Triggers: EventListeners and interceptors
The EventListener documentation describes EventListeners as effectively Tekton clients that use HTTP to bypass the normal Kubernetes authentication mechanism, which makes the interceptor chain your authentication layer.
- Signature validation: configure secretRef on the GitHub interceptor (and on GitLab and Bitbucket Server interceptors) with the same secret set on the webhook. For Bitbucket Cloud, the interceptor docs describe eventTypes filtering rather than shared-secret validation, so pair it with network controls on the sink. For GitHub Enterprise, enable interceptors.github.use-enterprise-host-allowlist and list hosts in github.enterprise-host-allowlist.
- Payload validation: enabled by default; the tekton.dev/payload-validation: "false" annotation turns it off and should appear only where an interceptor (such as Slack's) requires it.
- Filtering: use CEL filter expressions to accept only the events, branches and repositories a Trigger should act on.
- Service account: bind the EventListener account with a RoleBinding to tekton-triggers-eventlistener-roles and a ClusterRoleBinding to tekton-triggers-eventlistener-clusterroles, nothing broader. A Trigger can name its own serviceAccountName (the EventListener then needs impersonate on serviceaccounts), which lets you separate privileges per Trigger.
- Exposure and TLS: the sink Service el-<name> defaults to ClusterIP on port 8080. Expose it through an Ingress or load balancer with TLS, or set TLS_CERT and TLS_KEY from a secret on the sink. Harden the sink pod through spec.resources, for example runAsNonRoot: true and readOnlyRootFilesystem: true as in the documented example.
- namespaceSelector: a quoted "*" in matchNames lets one EventListener use Triggers from every namespace. Prefer one EventListener per namespace in multi-tenant clusters.
Trusted Resources
Trusted Resources, an alpha feature, verifies remote Tasks and Pipelines fetched from Git, OCI registries and Artifact Hub. Authors sign definitions with tkn sign (Tekton CLI v0.28.0 or later), which adds a tekton.dev/signature annotation. A VerificationPolicy (tekton.dev/v1alpha1) in the same namespace as the runs lists resource URL patterns and authorities, with keys from secretRef, inline data or a kms URI. Mode is enforce by default or warn. If several policies match, all must pass. Roll out in three steps: create policies in warn mode and watch the TrustedResourcesVerified condition; switch policies to enforce; then set trusted-resources-verification-no-match-policy (default ignore) to fail so unmatched sources cannot run. Roll back by returning the flag to warn. Public keys in the config-trusted-resources ConfigMap are deprecated in favour of VerificationPolicy.
Tekton Chains
Chains observes completed TaskRuns and PipelineRuns, converts them to a payload format, signs them and stores the result. Key settings in the chains-config ConfigMap:
| Key | Default | Recommended setting |
|---|---|---|
| artifacts.taskrun.format and artifacts.pipelinerun.format | in-toto | slsa/v1, or a newer slsa format your verifiers accept |
| artifacts.taskrun.storage | tekton | oci (beside the image) or a dedicated store such as archivista or docdb |
| artifacts.oci.signer | x509 | kms where available |
| signers.kms.kmsref | unset | A gcpkms://, awskms://, azurekms:// or hashivault:// key URI |
| signers.x509.fulcio.enabled | false | true for keyless signing with workload identity |
| transparency.enabled | false | true (or manual) to record signatures in a Rekor log |
| artifacts.pipelinerun.enable-deep-inspection | false | true so task-level results inside a pipeline are captured |
A static key lives in the signing-secrets secret in tekton-chains, as x509.pem (an unencrypted PKCS8 ed25519 or ecdsa key) or cosign.key with cosign.password. Anyone who can read that secret can sign as your build system, so move to KMS or keyless signing where you can. Provenance only describes what the Task reported: Tasks must emit type-hinted results for the image URL and digest for Chains to attest the right artefact. See the SLSA and Build Provenance Guide and the Sigstore Guide.
Logging and detection
| Source | Event to watch | Why |
|---|---|---|
| Kubernetes audit log | Updates to feature-flags, config-defaults, chains-config and resolvers-feature-flags; reads of signing-secrets | Security settings and signing keys change silently otherwise |
| Kubernetes audit log | TaskRun and PipelineRun creation naming privileged service accounts, by unexpected users | Run creation is the path to a service account's secrets |
| Run status | TrustedResourcesVerified False; Succeeded False after an enforced check | Unsigned or tampered definitions |
| EventListener sink logs | Rejected signatures and interceptor failures | Forged or replayed webhooks |
| Chains | Runs that complete without a signature or provenance entry | Gaps in the provenance record |
| Admission policy reports | Pods in pipeline namespaces violating the restricted profile | Steps running privileged or as root |
Map detections to ATT&CK T1195.002 (software supply chain) and T1552.007 Container API. Metrics that show progress:
- Percentage of runs that set an explicit, non-default service account.
- Percentage of remote Tasks and Pipelines covered by an enforcing VerificationPolicy.
- Percentage of release images with signed slsa provenance stored and verifiable.
- Number of EventListener Triggers without signature validation (target zero, except documented Bitbucket Cloud cases behind network controls).
- Count of long-lived Git and registry tokens on run service accounts, and their age.
Hardening baseline
- Inventory: list namespaces with Tekton runs, their service accounts and attached secrets, EventListeners and their exposure. Apply Tekton releases promptly and follow the project's release notes.
- Change the default account: set default-service-account to a minimal account with no secrets, then add explicit serviceAccountName to every PipelineRun template.
- Tighten pods: enable set-security-context, apply the restricted Pod Security Standard to pipeline namespaces, and test builds in a pilot namespace first.
- Narrow credentials: repository-scoped tokens, known_hosts enforcement, and per-step mounts or disable-creds-init for sensitive pipelines.
- Lock down triggers: secretRef on every interceptor that supports it, CEL filters, TLS on the sink, and documented Triggers roles only.
- Control definitions: disable unused resolvers, block inline specs in production, sign Tasks and roll out Trusted Resources from warn to fail.
- Sign outputs: configure Chains with KMS or keyless signing, slsa format, transparency and deep inspection, and verify signatures at deployment admission. See the Kubernetes Admission Control Guide.
Common misconfigurations
- Runs on the default account. Teams bind extra rights to default in a namespace to make a pipeline work, and every run there inherits them.
- Push credentials on build service accounts. Every step, including third-party Tasks from a catalogue, can read them through credential initialisation.
- GitHub interceptor without secretRef. Events are accepted without signature checks, so anyone who can reach the sink can start pipelines.
- Trusted Resources left in warn. Warnings are logged but nothing is blocked; set a date to move to enforce and fail.
- Chains signing with a widely readable secret. Broad read access on tekton-chains makes provenance forgeable. Restrict it and prefer KMS.
- Cluster-wide namespaceSelector. One EventListener service account then creates resources across tenants.
Framework mapping
| Control area | NIST SP 800-53 Rev 5 | NIST CSF 2.0 | ISO/IEC 27001:2022 Annex A |
|---|---|---|---|
| Run and trigger service account least privilege | AC-6 | PR.AA-05 | A.8.2 Privileged access rights |
| Pipeline credentials | IA-5 | PR.AA-05 | A.5.17 Authentication information |
| Signed definitions and provenance | SR-4, SI-7 | PR.PS-01 | A.8.25 Secure development life cycle |
| Secure pipeline configuration | CM-6, SA-15 | PR.PS-01 | A.8.9 Configuration management |
| Monitoring | AU-2, AU-6 | DE.CM-09 | A.8.15 Logging |
CIS Controls v8.1 Control 16 (Application Software Security) covers the secure build process. The OWASP CI/CD Top 10 maps closely; see the OWASP CI/CD Top 10 CICD-SEC-4 Poisoned Pipeline Execution Guide.
Practitioner checklist
- Set default-service-account to a minimal account and give every pipeline an explicit service account.
- Keep deployment and registry push credentials in namespaces where only release automation can create runs.
- Mount secrets only into the steps that need them, or set disable-creds-init for sensitive pipelines.
- Require known_hosts for SSH Git secrets with require-git-ssh-secret-known-hosts.
- Configure secretRef and CEL filters on every interceptor, and serve the EventListener over TLS.
- Enable set-security-context and apply the restricted Pod Security Standard to pipeline namespaces.
- Disable unused resolvers and block inline specs in production.
- Sign Tasks and Pipelines and move Trusted Resources to enforce with the no-match policy set to fail.
- Configure Chains with KMS or keyless signing, slsa provenance, transparency and deep inspection.
- Alert on changes to Tekton ConfigMaps and on reads of signing-secrets.
Standards and references
- Tekton: Authentication at Run Time
- Tekton: Additional Configuration Options
- Tekton: Trusted Resources
- Tekton: EventListeners
- Tekton: Interceptors
- Tekton: Chains Configuration
- Tekton: Chains Signing
- NIST: SP 800-53 Rev 5 Security and Privacy Controls
Related NHI Mgmt Group resources: GitOps Security Guide · Software Supply Chain Security Guide · Kubernetes NHI Security Guide · Secrets Management Guide