Skip to main content

Render Killed the Pasted AWS Key. Your Self-Hosted PaaS Is Now on the Clock.

9 min readDora NodaDora Noda
Share
On this page

Of 10,616 leaked AWS key pairs that researchers re-tested on August 10, 2026, 9,308 still authenticated. Eighty-eight percent. Four years after Truffle Security started tracking them across git history, Docker images, CI logs, and public datasets, the keys were still live — including 526 root keys and 242 IAM keys with full administrator access.

Read that again: hundreds of credentials granting total control over corporate AWS accounts, sitting in public, still working. Not because attackers are brilliant, but because nobody revoked them. The long-lived access key is a secret that outlives every human intention attached to it. It gets pasted into an env var, screenshotted into a runbook, baked into an image layer, and then it lives forever.

This is the world Render just voted to leave. On July 15, 2026, Render graduated Render-to-AWS OIDC authentication to general availability, and on July 24 it extended managed OIDC to Anthropic and OpenAI. A hosted web service can now call AWS, Claude, or OpenAI APIs with minted, short-lived identity instead of a pasted key. No rotation runbook. Nothing to leak.

That changes the baseline for everyone else. The moment a mainstream PaaS ships keyless cross-cloud auth as a GA feature, "paste your AWS_SECRET_ACCESS_KEY into the dashboard" stops being a reasonable default and starts being a liability you chose. If you run a self-hosted platform on machines you own, here is what Render shipped, how the machinery works, and what you need to build to match it.

What Render Actually Shipped

The timeline is short. In June 2026, Render put AWS OIDC authentication into early access. On July 15, it went GA for Pro workspaces and higher: any Render service can assume an AWS IAM role at runtime, with Render automatically issuing and rotating the temporary credentials each service uses. Nine days later, on July 24, managed OIDC gained Anthropic and OpenAI alongside AWS, so the same service identity that reaches S3 can reach the Claude and OpenAI APIs without storing sk-ant-... or sk-... keys anywhere.

The setup shape is deliberately boring, which is the point. For AWS: register Render as an IAM identity provider, create the trust relationship, and assign a role to each service with the AWS_ROLE_ARN environment variable. For Anthropic and OpenAI: connect Render as an identity provider, map the service account, add the required env vars, redeploy. After that, Render makes the service's OIDC token available at runtime and handles rotation invisibly.

Note what the developer never touches: no key generation, no key storage, no rotation calendar, no 2 a.m. "rotate everything" incident when a key shows up in a log. The secret with infinite lifetime has been replaced by an identity with a short one. That is the entire security upgrade, and it is enormous — the Truffle numbers above are what the old model costs in practice.

The Machinery in 90 Seconds

Nothing here is Render-proprietary. The flow is standard OIDC federation, the same pattern GitHub Actions has used for years:

  1. The platform runs an OIDC issuer with a public discovery document and JWKS endpoint.
  2. At runtime, the platform mints a signed JWT for the workload, with claims describing it (which service, which environment, which deployment).
  3. The workload presents that JWT to the target — AWS STS AssumeRoleWithWebIdentity, or Anthropic/OpenAI workload-identity federation endpoints — and exchanges it for short-lived credentials scoped to a role or service account.
  4. The target validates the signature against the issuer's JWKS, checks the claims against its trust policy, and issues credentials that expire in minutes to hours.

The trust policy is where the real access control lives. On the AWS side, the IAM role's trust policy constrains which aud (audience) and sub (subject) claims it accepts, so a token minted for service A cannot be replayed to assume service B's role. Anthropic and OpenAI's workload-identity federation works the same RFC 8693-shaped way: your OIDC token goes in, a short-lived provider-issued access token scoped to a service account comes out.

Why this beats static keys is worth stating plainly, because "keyless" gets hand-waved too often:

PropertyPasted access keyOIDC federation
LifetimeInfinite until rotatedMinutes to hours, auto-rotated
Blast radius of a leakFull key permissions, foreverToken expires before most exfiltration completes
RotationManual runbook, usually skippedAutomatic, nothing to rotate
RevocationFind every copy, then rotateDisable the trust policy entry
Audit trail"Some holder of the key"Per-workload claims in every assumption

Every row in the right column is something the platform does once, centrally, instead of something every developer does forever, individually. That asymmetry is why GA matters: it moves keyless auth from "sophisticated teams do this" to "the platform does this for you."

The New Baseline for Owned Machines

Here is the uncomfortable part. Render's version works because Render vouches for the workload: Render runs the issuer, holds the signing keys, serves the JWKS, and rotates everything. The trust boundary is Render's infrastructure, and AWS trusts Render's word about which service is calling.

On machines you own, there is no Render. You are the issuer. That is strictly more work, but it is also strictly more control — and the ecosystem has converged on two concrete ways to do it.

Path 1: Federate your cluster's own OIDC issuer. Every Kubernetes cluster already mints OIDC tokens: projected service-account tokens are JWTs signed by the cluster, with sub claims naming the namespace and service account. AWS IAM, Google Cloud workload identity, and Azure federated credentials can all trust a cluster issuer directly — this is the same mechanism behind EKS IRSA and GKE Workload Identity, and it works on any cluster whose issuer URL is reachable, including a Cluster-API-managed fleet on Hetzner. Your per-tenant scoping comes free from the claim structure: trust policy allows system:serviceaccount:tenant-a:deployer, and tenant B's pods cannot assume tenant A's role no matter what they present. No extra components, no new trust domain — just registration and tight trust policies.

Path 2: Run SPIFFE/SPIRE as your own identity plane. Where Path 1 borrows Kubernetes' issuer, SPIRE gives every workload a SPIFFE ID (spiffe://trust-domain/path) backed by node plus workload attestation, issuing short-lived X.509 or JWT SVIDs over the Workload API. The workload never holds a meaningful secret — it proves its identity to the local SPIRE agent by PID, and the agent resolves container to pod to identity. JWT-SVIDs then federate onward: AWS accepts them via IAM OIDC providers, and both Anthropic and OpenAI list SPIFFE among the identity providers their workload-identity federation accepts. This is the fuller answer — identity that survives beyond Kubernetes pod boundaries to VMs, bare metal, and agent sandboxes — at the cost of operating the SPIRE server, its attestation plugins, and its CA rotation yourself.

Be honest about the caveats, because the trust boundary moved onto your floor. Running the issuer means key custody, JWKS availability, and rotation discipline are yours now; an issuer outage is an auth outage for every federated target. Attestation is strong but not magic: Unit 42's September 2026 "Spooffe" research showed root on a Kubernetes node can spoof cgroup metadata and harvest co-located SPIRE workload SVIDs — node compromise still compromises workload identity, exactly as it compromises everything else on the node. And federation multiplies trust relationships: each AWS account, each Anthropic org, each OpenAI project needs its own registration of your issuer. That is configuration surface you must manage, preferably as code, with per-tenant scoping from day one rather than a wildcard trust policy you promise to tighten later.

The gap between the two paths is real but both clear the bar Render set: no long-lived keys in env vars, short-lived minted identity per workload, per-tenant scoping enforced by the target's trust policy rather than by developer discipline.

Your Fleet's Checklist

Concretely, here is what "match the Render baseline" means for a self-hosted fleet:

  • Expose a stable OIDC issuer per cluster. Projected service-account tokens with a reachable discovery URL, or a SPIRE deployment with JWT-SVID issuance. Pin the issuer URL — it is the identity anchor everything else references.
  • Register the issuer with every target. AWS IAM identity providers per account, Anthropic and OpenAI workload-identity providers per org. Automate this; manual console clicks do not survive your third tenant.
  • Scope trust policies by claims, per tenant. sub matching system:serviceaccount:<tenant>:* or the equivalent SPIFFE path prefix. Wildcard trust policies are the new pasted key — same blast radius, trendier mechanism.
  • Keep TTLs short. Minutes for JWT-SVIDs and projected tokens, hours at most for exchanged cloud credentials. Short lifetimes are the entire blast-radius story.
  • Delete the env-var keys. The migration is not done when federation works; it is done when the old keys are revoked. Audit every service for AWS_SECRET_ACCESS_KEY, ANTHROPIC_API_KEY, and OPENAI_API_KEY, federate each call site, then revoke. The Truffle statistic exists because step two never happened.
  • Monitor assumption, not just issuance. Log and alert on AssumeRoleWithWebIdentity calls the way you would on any other privilege use. The claims in the token tell you exactly which workload assumed which role — that auditability is a feature static keys never had.

"Done" has a crisp definition: a leaked environment dump from any tenant yields zero credentials that work anywhere, because there are no long-lived credentials left to leak.

Keyless Is Table Stakes Now

The direction of travel has been obvious for years — GitHub Actions, EKS IRSA, GKE Workload Identity, and now Anthropic and OpenAI all converging on OIDC federation and RFC 8693 token exchange. What Render's July GA changed is who has to think about it: nobody on Render anymore. The platform vouches, the tokens rotate, the keys never exist.

Self-hosting has always meant owning the undifferentiated heavy lifting in exchange for owning the machines. Workload identity just joined the list of things a credible platform does for its tenants rather than asking them to do for themselves. The issuers exist, the federation endpoints exist, the trust-policy primitives exist. What remains is the decision to build it — before your keys show up in someone else's four-year leak study.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex