Penv Cloud
Start free
Docs
Guidesince cloud@2026-09-10

External Secrets Operator

Point the External Secrets Operator webhook provider at GET /api/v1/bulk-read-secrets to read a whole environment in one request.

Not verified yet

This page is an outline. Nothing here has been confirmed against source, so do not follow it as product behavior.

The operator's webhook provider reads one of our routes and writes a Kubernetes Secret in your cluster. We ship no Kubernetes sync integration because this path exists.

We have not checked a ClusterSecretStore manifest against a running operator, so we show none. Take the provider schema from the External Secrets Operator documentation for your version and map it onto the request and response below.

Request

GET /api/v1/bulk-read-secrets
Authorization: Bearer pck_...
PartValue
Permissionsecret:reveal (not secret:read, which only lists names)
Body, query stringNone. We take workspace, project, and environment from the credential.

Operation reference: bulk read secrets.

Response

{
  "values": {
    "DATABASE_URL": "...",
    "redis/password": "..."
  },
  "skipped": ["stripe/rotating-key"]
}

values is flat: a root key is its bare name, a key under a path is path/name, the same naming an export sync uses. We send skipped only when it is non-empty.

In skippedReason
A dynamic addressMinted on request; no stored value. See dynamic values.
A key with no versionCreated, never written. Absent, not empty.

Check skipped in your tooling. A needed key in skipped is missing from the Secret, and a missing variable at pod boot is harder to diagnose than a refusal here.

Audit and rate cost

We open each value through the single-read path and record one secret.read entry with the credential (the audit log). A one-minute refresh over 40 keys is 40 entries a minute; set your refresh interval accordingly.

We admit a bulk read at a cost of one, then take one rate-limit token per value opened (a dynamic address costs nothing). See rate limits.

Refusals

StatuserrorCause
401unauthorizedCredential unknown to us.
401expiredCredential past its expiry.
403forbiddenThe credential's role lacks secret:reveal.
429rate_limitedIP ceiling (1000 requests a minute, checked before the credential) or the plan's per-identity bucket. retry-after gives seconds.

Full list: errors.

Setup

Create a machine identity in the console (machine identities) bound to the project and environment the operator reads, with a role carrying secret:reveal, and issue a pck_ credential. To avoid manual rotation, give the operator's service account a trust and exchange its projected token instead, as on Kubernetes.

Store the credential in a Kubernetes Secret in the operator's namespace.

Configure the webhook provider for GET /api/v1/bulk-read-secrets, sending the credential in the Authorization header.

Map values onto the keys the ExternalSecret requests.

Set the refresh interval, apply, and check the first sync.