AWS and Cloudanix team co-authored this blog: Real-Time Threat and Anomaly Detection for Workloads on AWS
Agentic JIT · for CI/CD, pods, services & AI agents

Non-human access.
without standing AdministratorAccess on your CI box, without permanent IRSA on every pod, without long-lived access keys in 47 GitHub Actions, scoped to the 30 seconds the operation actually needs

Today, Jenkins runs under one permanent role with AdministratorAccess — or a 200-line policy that grew organically. Every pod in your EKS cluster sharing a Service Account inherits its IAM role forever. Agentic JIT flips that: register an Agent in Cloudanix once, then your pipeline / pod / function calls our SDK or native CI library to elevate for the few seconds it actually needs the privilege, runs the operation, revokes. TTL is a hard ceiling. Audit links the API call to the agent, the workflow, the commit, the pod.

✓ Jenkins · GitHub Actions · GitLab CI · Bitbucket · CircleCI · ArgoCD · raw API ✓ EKS Pod Identity · IRSA · GKE Workload Identity · ECS · Fargate · Lambda ✓ AWS · Azure · GCP · multi-account · short-lived tokens · audited end-to-end
Register New Agent Step 1 of 3
Name jenkins-deploy-agent
Description Jenkins CI · deploys main to prod ECS
Use case Build Workflow Cloud Workload Pod Identity Other
Max session 10 min 30 min 1 hr 2 hr 4 hr
Auth mode Static Principal · AWS IAM Role
Jenkinsfile · @Library('cloudanix-jit')
wrap the privileged step · not the whole pipeline
cloudanix-jit · shared library v3.4
@Library('cloudanix-jit') _
pipeline { agent any
  stages { stage('Deploy') {
    steps { cloudanixElevate(
      policy: 'AmazonECS-FullAccess', ttl: '15m'
    ) { sh 'aws ecs update-service ...' } } } } }
Jenkins · my-app · build #142 · console output
commit a7c1f24 · main
✓ elevatepolicy attached · AmazonECS-FullAccess · 15m
→ shaws ecs update-service · cluster prod · service api
✓ revokepolicy detached · audit → S3
elevated for 38 seconds · of a 4-minute build not the whole pipeline
The problem

Your non-human identities are the biggest blast radius you have.

You spent a year tightening human access — SSO, MFA, JIT to consoles. Meanwhile your Jenkins box runs with AdministratorAccess 24/7, every pod shares an SA, and a 200-line CI policy nobody understands gets s3:* “just to unblock the release.” Shell on the CI box equals shell on prod.

🛠

Jenkins owns the keys to the kingdom

Your CI host runs with a permanent IAM role that has AdministratorAccess, or a 200-line policy that grew organically over three years. Anyone who pops shell on that host, or a malicious dependency in a build step, inherits the entire blast radius for the lifetime of the box. The cleanup story is “rotate the role.” The reality is nobody rotates it.

📦

Every pod inherits the SA forever

EKS Pod Identity / IRSA bind at the Service Account level — every pod sharing an SA inherits its IAM role permanently. So one shared app-sa ends up wired to S3, KMS, RDS, Secrets Manager, all the time, for everyone. New pod deployed? Inherits everything. A compromised image? Inherits everything.

🔑

Long-lived keys in 47 workflows

GitHub Actions, GitLab CI, Bitbucket Pipelines — each repo's secrets store has a long-lived access key. 200 repos × an average of 3 secret variables = 600 standing credentials. Each rotation is a quarterly tax. Each leak is the next post-mortem. Most never get rotated.

🧾

Audit dies at the federated role

CloudTrail says JenkinsDeployRole deleted the bucket. Which build? Which commit? Which engineer's PR triggered it? The trail ends at the role name. Same for pods — which pod called the API? The SA can't tell you. Auditors want the chain.

How it works

Register once. Elevate at runtime. Revoke on completion.

One model for every non-human identity in your stack — Jenkins jobs, GitHub Actions, EKS pods, Lambda functions, ECS tasks, AI agents. The runtime integration is a single SDK call or one line in your CI library.

  1. 1

    Register the Agent

    In the Cloudanix console: give the agent a name, pick a use case (Build Workflow · Cloud Workload · Pod Identity · Other), set a max session duration. This is the one-time admin action — a human controls the boundary, not the pipeline.

  2. 2

    Define the cloud boundary

    Target cloud (AWS · Azure · GCP), auth mode (Static Principal, Static Access Keys, and the upcoming Dynamic Access Keys & Dynamic Role), account, principal (IAM Role / Service Account), and the policies this agent is ever allowed to be granted. Out-of-bounds requests are denied at the API.

  3. 3

    Wire the SDK or native CI library

    Use the Jenkins shared library, the Cloudanix GitHub Action, the GitLab CI template, the Bitbucket Pipe, or the raw API from anything else. Two secrets per repo (CLOUDANIX_AUTH_TOKEN · CLOUDANIX_AGENT_ID) and you're wired.

  4. 4

    Elevate around the privileged step

    At runtime, the agent calls elevate() with the policy and a TTL. Cloudanix checks the boundary, attaches the policy to the role (or hands back short-lived STS credentials), and returns. The build / pod / function runs the operation that actually needs the privilege — usually 30 seconds inside a four-minute job.

  5. 5

    Revoke on completion (or TTL hits)

    The wrapper detaches the policy the moment the privileged block exits — or the pod's preStop hook calls revoke(). If the agent forgets, the max session TTL is a hard ceiling. The full lifecycle (register, elevate, action, revoke) lands in your S3 bucket as one correlated audit trail, linked to the workflow / commit / pod that triggered it.

Use cases

Four flavours of non-human. One JIT engine.

CI/CD, cloud workloads, Kubernetes pods, and the long tail of bespoke services and AI agents. Each is a different integration surface; all of them share the same register-elevate-revoke contract.

use case · Jenkins · deploy to prod ECS · 15m
jenkins-deploy-agent (CI) Pipeline needs AmazonECS-FullAccess for the aws ecs update-service step. 30 seconds of privilege inside a 4-minute build, then it's gone.
Jenkins · build #142
🛠
cloudanixElevate()
Cloudanix JIT
attach policy
JenkinsDeployRole
scope granted policy: AmazonECS-FullAccess · ttl: 15m · workflow: my-app #142 · commit: a7c1f24
◎ elevate · agent: jenkins-deploy-agent
✓ Policy attached at 14:00:14 · AmazonECS-FullAccess
✓ Action: ecs:UpdateService · cluster prod · service api
✓ revoke() called at 14:00:52 · policy detached
✓ Elevation duration: 38s · TTL was 15m
✓ Stamped agent → workflow → commit → action ⛔ Revoked · 14:00:52 (38s after grant)
use case · EKS pod · payments-api · S3 read · lifecycle
payments-api-agent (EKS pod) Pod boots, calls elevate. Reads its receipts bucket for the lifetime of the workload. preStop hook calls revoke. SA loses access — even cached STS tokens.
⚠ Pod Identity binds at SA level · 1 SA per workload ✓ Enforced by Cloudanix policy
EKS pod · startup
📦
SDK elevate
Cloudanix JIT
Pod Identity Association
SA → IAM Role
scope granted cluster: prod · ns: payments · sa: payments-api · policy: S3ReadOnly · ttl: pod-lifecycle
◎ elevate · agent: payments-api-agent
✓ Pod Identity Association created at 10:14:02
✓ Pod reads s3://pmt-receipts/ for ~6h
◎ preStop hook fires at 16:32:11
✓ revoke() called · association deleted · cached tokens invalidated
✓ Stamped agent → pod → SA → action ⛔ Immediate revoke · no 1-hour STS hangover
use case · ECS task · nightly DB export · 20m
nightly-export-agent (ECS task) ECS scheduled task runs once a night. Needs to read from RDS, write to S3. Elevate at 02:00, run the export, revoke at 02:20 — whether the task succeeded or failed.
ECS task · cron
SDK elevate
Cloudanix JIT
attach policy
ExportTaskRole
scope granted policy: ExportReadWrite · ttl: 20m · task: nightly-export · run: 2026-06-08
◎ elevate · agent: nightly-export-agent
✓ Policy attached at 02:00:01
✓ Action: rds:DescribeDBInstances · s3:PutObject (×142)
✓ Task exit code: 0 · revoke called at 02:18:44
✓ Policy detached · TTL was 20m
✓ Stamped agent → task run → action chain ⛔ Revoked even on task failure (try/finally)
use case · AI agent · on-call triage · per-action
oncall-triage-agent (LangChain bot) Internal agent triages PagerDuty alerts. Per diagnosis step it elevates just-enough cloud read — describe instance, get CW metric — for 60 seconds. Never holds standing privilege between steps.
AI agent step
🤖
raw API elevate
Cloudanix JIT
scoped STS
ReadOnly · scoped
scope granted policy: ReadOnlyAccess · ttl: 60s · per-step · ref: PD-9211
◎ elevate · agent: oncall-triage-agent · step 1/4
✓ STS issued · ttl 60s
✓ Action: ec2:DescribeInstances · cloudwatch:GetMetricData
✓ Step complete · STS expired (no explicit revoke needed)
◎ elevate · step 2/4 · new TTL, narrower scope
✓ Stamped agent → incident → step → action ⛔ Zero standing privilege between steps
native libraries & runtimes Jenkins GitHub Actions GitLab CI Bitbucket Pipelines CircleCI ArgoCD AWS CodeBuild EKS · Pod Identity EKS · IRSA GKE Workload Identity AKS workload identity ECS · Fargate Lambda Step Functions …anything that can speak HTTPS · raw API
The model

Devs ship faster. Security finally has a chain of custody.

What platform & dev teams get
  • No more “why does this Lambda 403?” — per-step elevation, no role-sprawl debugging
  • Drop in a Jenkins shared library, a GitHub Action, or one SDK call — pipelines stay where they are
  • Stop rotating long-lived keys across 47 workflows — auth tokens are agent-scoped
  • Build engineers read the policy bounds in code review — no opaque IAM console digging
one SDK call. zero standing creds.
What security keeps
  • Zero standing access on every NHI — Jenkins, pods, ECS tasks, AI agents
  • Multi-cloud (AWS · Azure · GCP) under one boundary policy — per-agent, per-account, per-policy
  • Bounded max-session-duration enforced at the API — the pipeline can't request 8h if the agent caps at 1h
  • One audit linking action → agent → workflow → commit / pod / SA — the trail no longer dies at the federated role
Governance & audit stay in your account.
Unified audit timeline

One audit trail per elevation. Linked to the workflow that triggered it.

Every Agentic JIT grant becomes one correlated timeline — SDK call, boundary check, IAM event, every API action made under the elevated identity, revoke, audit persist. The trail no longer stops at JenkinsDeployRole did it — it points back to the agent, the build, the commit, the pod.

elevation timeline · elev-9c11f3a8 · jenkins-deploy-agent · build #142
[14:00:14]  ELEVATE      jenkins-deploy-agent · AmazonECS-FullAccess · 15m
[14:00:14]  POLICY-CHECK boundary OK · within agent permitted policies
[14:00:15]  IAM EVENT    attach-role-policy → JenkinsDeployRole
[14:00:18]  ACTION       ecs:UpdateService · cluster prod · service api
[14:00:19]  ACTION       ecs:DescribeServices · cluster prod
[14:00:52]  REVOKE       SDK call from pipeline · build step finished
[14:00:52]  IAM EVENT    detach-role-policy → JenkinsDeployRole
[14:00:53]  AUDIT        written to s3://your-bucket/jit-agents/
1:14 / 2:00
agent · jenkins-deploy-agent workflow · my-app #142 commit · a7c1f24 ttl · 15m (used 38s)
  • End-to-end elevation, one view

    SDK call → boundary check → IAM event → every API action under the elevated identity → revoke. No more correlating CloudTrail with Jenkins build logs with the GitOps PR.

  • 🧾

    Evidence-grade for SOC 2 · ISO · PCI

    Pull a quarterly report of every elevation by every NHI — agent, workflow, commit, action chain, exact-second revoke. Auditors love the “agent → commit” link — no more “the CI box did it.”

  • 🔗

    Sits in your data plane

    Audit writes to your S3 / Azure Blob / GCS, not ours. Send your auditor a signed URL scoped to one elevation or a whole quarter. The link expires. Nothing copied, nothing leaked.

Plugs in · doesn't replace

Your CI/CD. Your runtimes. Our JIT in between.

Cloudanix sits between your pipelines / runtimes and the cloud IAM systems they depend on. Jenkins stays Jenkins. EKS stays EKS. AWS IAM stays the source of truth. We just make the policies on the role / SA attach for 30 seconds, not forever.

CI/CD & pipeline orchestrators

Jenkins
GitHub Actions
GitLab CI
Bitbucket Pipelines
CircleCI
ArgoCD
AWS CodeBuild
Anything that speaks HTTPS · raw API

Cloud runtimes & workload identities

AWS
Azure
GCP
EKS · Pod Identity
EKS · IRSA
GKE Workload Identity
AKS workload identity
ECS · Fargate
Lambda
Step Functions
LangChain · CrewAI · agent frameworks
EC2 · on-prem workers
What you get

Everything a non-human-identity access program needs — without retrofitting every pipeline and pod.

Zero standing NHI access

Every CI job, every pod, every function gets the policy attached only when it's about to use it. The standing role behind it stays empty (or boring).

🧩

Native CI libraries · one SDK call

Jenkins shared library, GitHub Action, GitLab CI template, Bitbucket Pipe, Python & Node SDK, raw REST. Wire it once, every pipeline gets the same elevate() primitive.

Per-step, not per-pipeline

Elevate around the 30 seconds the deploy actually needs, not the 90-minute build. The blast radius is the 30s window, not the build host's entire lifetime.

Multi-cloud · multi-auth

AWS, Azure, GCP — one model. Auth modes: Static Principal, Static Access Keys, and the upcoming Dynamic Access Keys & Dynamic Role. Pick what fits the workload.

🧱

Boundary-enforced at the API

The agent registration is the boundary — a pipeline can't request a policy outside its agent's permitted set, can't exceed the max session duration. Mistakes get a 403, not a privilege escalation.

📦

Pod-lifecycle aware

For EKS Pod Identity / IRSA / GKE Workload Identity: elevate at pod start, revoke on preStop. Even cached STS tokens get invalidated — no one-hour ghost-credential window.

🧾

Action → agent → commit audit

CloudTrail now answers which build, which commit, which pod — not just “the federated role.” Stored in your S3 / Blob / GCS, kept forever, signed on the way in.

🔑

Kill long-lived workflow secrets

Two scoped, rotatable creds per pipeline (CLOUDANIX_AUTH_TOKEN · CLOUDANIX_AGENT_ID) replace the 600 long-lived access keys spread across your repos. One control plane, one rotation policy.

🌐

One JIT engine · humans & non-humans

The same Cloudanix that gives an engineer JIT into the AWS console also gives Jenkins JIT to call ecs:UpdateService. Same policy model, same audit pipeline, one team of operators.

Ready to see your graph?

Connect a cloud account in under 30 minutes. See every finding rooted in identity, asset, and blast radius — with a fix path attached.

Book a Demo