{"id":49569186,"url":"https://github.com/cloudflare/kubernetes-access-worker-example","last_synced_at":"2026-05-23T15:02:38.420Z","repository":{"id":359008437,"uuid":"1133798944","full_name":"cloudflare/kubernetes-access-worker-example","owner":"cloudflare","description":"Example implementation of an Access-protected private Kubernetes API","archived":false,"fork":false,"pushed_at":"2026-04-23T21:01:26.000Z","size":127,"stargazers_count":4,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-20T04:03:24.734Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudflare.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-13T20:45:23.000Z","updated_at":"2026-05-01T16:15:30.000Z","dependencies_parsed_at":"2026-05-20T04:03:35.908Z","dependency_job_id":null,"html_url":"https://github.com/cloudflare/kubernetes-access-worker-example","commit_stats":null,"previous_names":["cloudflare/kubernetes-access-worker-example"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/cloudflare/kubernetes-access-worker-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudflare%2Fkubernetes-access-worker-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudflare%2Fkubernetes-access-worker-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudflare%2Fkubernetes-access-worker-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudflare%2Fkubernetes-access-worker-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudflare","download_url":"https://codeload.github.com/cloudflare/kubernetes-access-worker-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudflare%2Fkubernetes-access-worker-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33400251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-03T13:00:33.039Z","updated_at":"2026-05-23T15:02:33.306Z","avatar_url":"https://github.com/cloudflare.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# Cloudflare Zero Trust Kubernetes Proxy\n\nThis repository contains a reference implementation for securely exposing a\nKubernetes API server using **Cloudflare Zero Trust**, **Cloudflare Workers**,\nand **Terraform**.\n\nUnlike a traditional VPN, this architecture places a Cloudflare Worker on the\npublic internet, strictly shielded by Cloudflare Access. Users authenticate\nusing their enrolled WARP client in your Zero Trust organization; Cloudflare\nAccess reuses this authenticated WARP session to automatically authorize\nrequests to the Worker for a configured [session\nduration](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/warp/configure-warp/warp-sessions/#configure-warp-sessions-in-access).\nOnce authorized, Access injects a signed JWT into the request headers; the\nWorker then cryptographically validates this token to confirm the user's\nidentity before proxying traffic to your Kubernetes API server using\n[Impersonation\nheaders](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation).\n\n## 🏗 Architecture\n\nThe flow of a request is as follows:\n\n1.  **Developer** runs `kubectl` on their laptop (connected to Cloudflare WARP).\n2.  **WARP** captures the request and attaches a secure device session identity.\n3.  **Cloudflare Access** checks the Zero Trust policy (i.e., \"Must have valid\n    WARP session\") before sending the traffic to the Worker.\n4.  **Cloudflare Worker** (this [code](./src/index.ts)):\n      * Validates the Access JWT.\n      * Maps the user `email` to a Kubernetes identity (User/Group).\n      * Establishes a secure, private connection to the cluster via Cloudflare\n        Tunnel and [Workers VPC (WVPC)](https://developers.cloudflare.com/workers-vpc/).\n      * Injects [Impersonation headers](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation).\n      * Handles WebSocket upgrades for streaming commands (`kubectl exec`, `logs -f`).\n5.  **Kubernetes API** receives the request. Once the Kubernetes API server\n    verifies the pod's Service Account has permission to `impersonate` (e.g.\n    `ClusterRole` with `impersonate` verb), it switches contexts and applies\n    standard Kubernetes RBAC policies to the request effectively as if User X\n    and Group Y had initiated it directly.\n\n## ⚡️ The Worker (`/src`)\n\nThe heart of this solution is the Cloudflare Worker. It is responsible for\nbridging the gap between HTTP-based Zero Trust auth and Kubernetes-native RBAC.\n\n### Key Features\n\n  * **Identity Mapping:** Translates enrolled Zero Trust user's email (e.g. `alice@mydomain.com`) into a Kubernetes User (e.g. `alice`) and Groups (e.g. `system:masters`, `developers`).\n  * **Header Sanitization:** Removes dangerous headers to prevent spoofing and strips internal Cloudflare trace headers before they reach the cluster.\n  * **WebSocket Support:** Full support for interactive `kubectl` commands (exec, attach, port-forward) by manually handling the WebSocket handshake and subprotocol negotiation.\n  * **Security:** Verifies the JWT signature against your Team's JWKS to ensure requests are legitimate.\n\n## ☁️ Infrastructure (Terraform)\n\nThe `/terraform` directory uses a modular approach to provision the entire\nstack.\n\n### 1. DigitalOcean Cluster ([`modules/digitalocean`](./terraform/modules/digitalocean))\n\n  * Provisions a managed Kubernetes (DOKS) cluster for demo purposes.\n  * Configures VPC and node pools.\n\n### 2. Kubernetes Resources ([`modules/k8s`](./terraform/modules/k8s))\n\n  * **Cloudflare Tunnel:** Creates the [Cloudflare\n    Tunnel](https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/)\n    and credentials.\n  * **Tunnel Pod (Sidecar Architecture):** Deploys a single Pod containing two\n    containers to bridge traffic from the edge to the API server:\n      * **Container 1 (`cloudflared`):** Establishes the encrypted outbound\n        tunnel to Cloudflare. It receives traffic from the edge and forwards it\n        locally via plaintext HTTP to the sidecar (traffic is fully encrypted in\n        transit through the tunnel).\n      * **Container 2 (`kubectl proxy`):** Runs the [`kubectl\n        proxy`](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_proxy/)\n        command. It listens for the plaintext traffic from `cloudflared` and\n        proxies it to the actual upstream Kubernetes API Server. This sidecar\n        validates the Kube API's TLS certificate.\n  * **Service Account:** Creates the high-privilege Service Account the Worker\n    uses to \"impersonate\" other users. It is bound to the pod; the Worker does\n    not see the secret `ServiceAccount` token.\n  * **RBAC:** Binds the necessary `ClusterRole` to allow the pod to perform\n    impersonation.\n\n### 3. Worker Infrastructure ([`modules/worker`](./terraform/modules/worker))\n\n  * **Worker Custom Domain:** Maps the Worker to a custom domain (e.g.,\n    `kube.mydomain.com`). This is a prerequisite for placing the Worker\n    behind Cloudflare Access.\n  * **Access Application:** Protects the Worker's public endpoint by enforcing\n    Zero Trust policies. It strictly verifies that incoming requests have a\n    valid, authenticated WARP session before they ever reach the Worker code.\n  * **Workers VPC Service:** Configures a [Workers VPC\n    Service](https://developers.cloudflare.com/workers-vpc/configuration/vpc-services/)\n    to create a secure, private binding (`env.KUBE_API`). This allows the Worker\n    to communicate directly with the Cloudflare Tunnel inside the cluster over a\n    private network, ensuring traffic between the proxy and the cluster never\n    traverses the public internet.\n  \n## 🚀 Deployment Guide\n\n### 🛠️ Step 0: Prerequisites \u0026 Setup\n\n**Prerequisites:**\n* **Zero Trust Admin:** You must be an Administrator in your [Cloudflare Zero Trust Organization](https://developers.cloudflare.com/cloudflare-one/setup/).\n* **Cloudflare Zone:** You need an active domain onboarded to Cloudflare. This\n  is required to assign a public custom domain (e.g., `kube.mydomain.com`) to the\n  Worker later.\n    * *Guide: [Add a site to Cloudflare](https://developers.cloudflare.com/fundamentals/setup/manage-domains/add-site/)*\n* **WARP sessions:** Enable `WARP authentication identity` as an allowed login\n  method in your Zero Trust Organization. This allows users to log in to Access\n  applications using their WARP session.\n  * *Guide: [Configure WARP sessions in Access](https://developers.cloudflare.com/cloudflare-one/team-and-resources/devices/warp/configure-warp/warp-sessions/#configure-warp-sessions-in-access)*\n\n**Required Tools:**\n* [Node.js](https://nodejs.org/) \u0026 [npm](https://www.npmjs.com/)\n* [Terraform](https://developers.cloudflare.com/terraform/installing/)\n\nBefore interacting with the Worker or deploying infrastructure, you must install\nthe project dependencies. This ensures `wrangler` and the necessary TypeScript\ntypes are available locally.\n\n1.  **Navigate to the project root:**\n\n    ```bash\n    cd kubernetes-access-worker-example\n    ```\n\n2.  **Clean Install Dependencies:** Use `npm ci` (Clean Install) to ensure you\n    install the exact versions defined in the `package-lock.json` file,\n    preventing version mismatch errors during deployment.\n\n    ```bash\n    npm ci\n    ```\n\n#### 🧠 Configuring Identity Mapping\n\nThe Worker contains a hardcoded lookup table that translates a user's email into\na specific **Kubernetes User and Group**. This is the core logic that determines\n\"Who is this person inside the cluster?\"\n\nBy default, the code includes a placeholder for demonstration. You **must**\nupdate this to match your actual team members and their desired permissions.\n\n1.  Open [`src/index.ts`](./src/index.ts).\n2.  Locate the `IDENTITY_MAP` constant.\n3.  Add entries for your team members, assigning them to the appropriate\n    Kubernetes RBAC groups (e.g., `system:masters` for admins, `view` for\n    developers).\n\n##### ⚙️ Advanced: Custom Identity Logic\n\nFor more dynamic control, you can modify the `mapAccessIdentityToK8s` function\nin `src/index.ts`. This function is the central decision point for\nauthorization; you can extend it to look up identities in Cloudflare KV, an\nexternal database, or apply regex patterns to specific teams.\n\n**⚠️ Important: Remove Demo Logic** Out of the box, this function contains a\n**catch-all demo rule** that grants `system:masters` (superuser) privileges to\n**any** user with a `@mydomain.com` email address.\n\n```typescript\n// src/index.ts\n\n// 🚨 TODO: REMOVE THIS BLOCK FOR PRODUCTION 🚨\nif (claims.email.endsWith(\"@mydomain.com\")) {\n  return {\n    accessJwtIdentity: claims.email,\n    // Does not matter since group is superuser, but still required for\n    // impersonation to specify username\n    user: \"foobar\",\n    groups: [\"system:masters\"],\n  };\n}\n```\n\nBefore deploying to a real environment, you **must remove or update this\nblock**. If you want to rely strictly on the `IDENTITY_MAP` defined above,\ndelete this `if` statement entirely to ensure only explicitly allowed users can\naccess the cluster.\n\n##### Example Configuration\n\n```typescript\nconst IDENTITY_MAP: Record\u003cstring, K8sIdentity\u003e = {\n  // Admin User: Grants full cluster control\n  \"alice@mydomain.com\": {\n    user: \"alice\", \n    groups: [\"system:masters\"] \n  },\n\n  // Developer User: Grants read-only access (assuming you have a 'view-only' ClusterRole)\n  \"bob@mydomain.com\": {\n    user: \"bob\",\n    groups: [\"view\", \"system:authenticated\"]\n  }\n};\n```\n\n### ⚡ Step 1: Bootstrap\n\nThis project requires a **two-stage deployment**. We must deploy the Worker\nfirst (even with invalid environment variables) so that Terraform can locate the\nWorker script and attach the necessary resources (Custom Domains, Access\nApplication) to it.\n\n1.  **Authenticate:** Log in to your Cloudflare account.\n\n    ```bash\n    npx wrangler login\n    ```\n\n    *Ensure your user has\n    [permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/#account-permissions)\n    to create and edit Workers (`Workers Scripts Write`).*\n\n2.  **Configure Identity \u0026 Routes:** Open `wrangler.toml` and update the\n    configuration to match your Cloudflare account and network settings.\n\n      * **`account_id`**: Cloudflare account ID. Found on the right sidebar of\n        the Cloudflare Dashboard.\n      * **`routes`**: Defines the public DNS record where this Worker will be\n        accessible (must match the Zone you are deploying to).\n      * **`ACCESS_TEAM_DOMAIN`**: Your Cloudflare Zero Trust URL (used to fetch\n        keys for JWT validation).\n\n    ```toml\n    # wrangler.toml\n\n    # Update with your Cloudflare account ID\n    account_id = \"\u003cCLOUDFLARE_ACCOUNT_ID\u003e\"\n\n    # Update with your Cloudflare zone and desired subdomain\n    routes = [{ pattern = \"kube.mydomain.com/*\", zone_name = \"mydomain.com\" }]\n\n    [vars]\n    # Don't modify other [vars]\n    # ...\n    # Update with your Zero Trust org team domain\n    ACCESS_TEAM_DOMAIN = \"https://my-zt-org.cloudflareaccess.com\"\n    ```\n\n3.  **Initial Deploy:** Push the code to create the Worker placeholder.\n\n    ```bash\n    npx wrangler deploy\n    ```\n\n    *(Note: The Worker will technically be \"live\" but will fail requests until\n    the Terraform infrastructure (Step 2) is applied and more environment\n    variables are set.)*\n\n### 🏗️ Step 2: Infrastructure Setup\n\nTerraform is used to deploy the infrastructure relevant to this project.\n\n#### 🔑 Cloudflare API Token Permissions\n\nTo successfully provision all resources (Tunnel, Worker, Access, and DNS), you\nmust provision a Cloudflare API Token with sufficient privileges. We strongly\nrecommend creating an **Account-Owned Token**. \n\nCreate a Custom Token with the following permissions:\n\n**Account Permissions:**\n* `Connectivity Directory` \u003e `Edit`\n* `Cloudflare Tunnel` \u003e `Edit`\n* `Zero Trust` \u003e `Edit`\n* `Workers Scripts` \u003e `Edit`\n* `Access: Apps and Policies` \u003e `Edit`\n\n**Zone Permissions:**\n* `Zone` \u003e `Read`\n* `DNS` \u003e `Edit`\n\n**Zone Resources:**\n* Set to **Include** \u003e **Specific Zone** \u003e Select your target domain (e.g., `mydomain.com`).\n\n#### ☸️ Bring Your Own Cluster (BYOC)\n\nBy default, this project provisions a fresh DigitalOcean Kubernetes cluster for\ndemo purposes. If you prefer to use an existing cluster (e.g., AWS EKS, GKE, or\na local Minikube), you must manually update the Terraform configuration to\nbypass the infrastructure provisioning:\n\n1.  **Disable the Infrastructure Module:** Open [`main.tf`](./terraform/main.tf) and comment out the\n    entire `module \"digitalocean\" { ... }` block.\n2.  **Remove Dependencies:** In the `module \"k8s\"` block, remove the line\n    `depends_on = [module.digitalocean]`.\n3.  **Update Variables:** Open [`variables.tf`](./terraform/variables.tf). Remove\n    the `do_token` variable block.\n4.  **Update Providers:** Open [`providers.tf`](./terraform/providers.tf).\n    Remove the `digitalocean` provider configuration and update the `kubernetes`\n    provider to point to your local kubeconfig file (or specific cloud context).\n\nUse the following configuration to target your current active cluster context:\n\n```hcl\n# providers.tf\n\nprovider \"kubernetes\" {\n  config_path    = \"~/.kube/config\"\n  # Optional: Specify a context if not using current\n  config_context = \"your-context\" \n}\n```\n\n### 🛡️ Access Policy Configuration\n\nBy default, the Terraform module creates a basic Access Policy for the Worker.\nYou must customize this to define exactly **who** in your organization is\nallowed to reach the proxy worker and therefore the Kubernetes API.\n\n1.  **Locate the Resource:** Open\n    [`terraform/modules/worker/main.tf`](./terraform/modules/worker/main.tf).\n2.  **Find the Policy:** Look for the `resource\n    \"cloudflare_zero_trust_access_policy\" \"policy\"` block.\n3.  **Update the `include` block:** Modify the rules to match your\n    organization's security groups.\n\n#### Example Configurations\n\n**Option A: Allow specific admins (Good for testing)**\n\n```hcl\nresource \"cloudflare_zero_trust_access_policy\" \"policy\" {\n  # ... existing config ...\n  decision = \"allow\"\n\n  include = [\n    { email = { email = \"alice@mydomain.com\" }},\n    { email = { email = \"bob@mydomain.com\" }}\n  ]\n}\n```\n\n**Option B: Allow an Access Group (Best Practice)**\n\nWe recommend creating a \"Platform Engineers\" group in your Zero Trust dashboard\nand referencing it here by UUID. This keeps your Terraform code clean and allows\nyou to manage membership via your IdP.\n\n```hcl\nresource \"cloudflare_zero_trust_access_policy\" \"policy\" {\n  # ... existing config ...\n  decision = \"allow\"\n\n  include [{\n    group = { id = \"044513ec-5875-4fce-87bd-a75f658fd9de\" }\n  }]\n}\n```\n\n**Option C: Allow entire email domain (Broad access)**\n\n```hcl\nresource \"cloudflare_zero_trust_access_policy\" \"policy\" {\n  # ... existing config ...\n  include = [{\n    email_domain = { domain = \"your-company.com\" }\n  }]\n}\n```\n\n#### ▶️ `terraform apply`\n\nNavigate to the terraform directory and run `terraform apply`.\n\n***\n\n\u003e **⚠️ Security Warning: Protect Your State File**\n\u003e\n\u003e When running Terraform locally, your state is stored in a `terraform.tfstate`\n\u003e file. This file contains **unencrypted sensitive data**, including your\n\u003e Cloudflare API tokens, Tunnel secrets, and Kubeconfig credentials.\n\u003e\n\u003e * **Do not commit** `terraform.tfstate` or `terraform.tfstate.backup` to\n\u003e   version control.\n\u003e * Ensure these files are listed in your `.gitignore`.\n\u003e * For production environments, use a secure [Remote\n\u003e   Backend](https://developer.hashicorp.com/terraform/language/settings/backends/remote)\n\u003e   (like Terraform Cloud or S3 with encryption) instead of local state.\n\n***\n\n```bash\ncd terraform\nterraform init\nterraform apply\n```\n\n*Note: You will need to provide your Cloudflare API Token, Account ID, and\nDigitalOcean Token as input variables.*\n\n### 🔗 Step 3: Bind WVPC \u0026 Final Deploy\n\nWith the infrastructure successfully provisioned, you must now connect the\nWorker to your new resources. You will use `terraform output` to retrieve the\nrelevant configuration data.\n\n#### ⚙️ Update Configuration\n\nOpen `wrangler.toml` and update the `[vars]` and `[[vpc_services]]` sections\nusing the values from your Terraform state:\n\n```toml\n# wrangler.toml\n\n[vars]\n# Don't modify other [vars]\n# ...\n# Application Audience (AUD) Tag for the Access Application protecting this worker.\n# Retrieve with: terraform output -raw access_aud\nACCESS_AUD = \"\u003cAUD_TAG\u003e\"\n\n# Uncomment this entire block and update the `service_id` with your WVPC service ID.\n[[vpc_services]]\nbinding = \"KUBE_API\"\n# The ID of the Workers VPC Service created by Terraform.\n# Retrieve with: terraform output -raw wvpc_service_id\nservice_id = \"\u003cWVPC_SERVICE_ID\u003e\"\nremote = true\n```\n\n#### 🚀 Final Deployment\n\n**Note**: Before deploying, ensure the Cloudflare user authenticated in your\nterminal (via `wrangler login`) possesses the `Connectivity Directory Bind`\nrole. This specific permission is required to bind a Worker to an existing WVPC\nService. If you encounter a \"binding\" error during deployment, verify that your\nuser account or API token has been granted this role in the Cloudflare\nDashboard.\n\nNow that the configuration and secrets are in place, deploy the fully functional\nWorker:\n\n```bash\nnpx wrangler types\nnpx wrangler deploy\n```\n\n## 💻 Client Configuration\n\nEnsure you have the **Cloudflare WARP Client** installed and enrolled in your\norganization's Zero Trust team.\n\nTo connect `kubectl` to this worker, you do not need to install plugins. You\nsimply update your `~/.kube/config` to point to the Worker's public URL.\n\n```yaml\napiVersion: v1\nclusters:\n- cluster:\n    server: https://kube.mydomain.com\n  name: cloudflare-k8s\ncontexts:\n- context:\n    cluster: cloudflare-k8s\n    user: warp-user\n  name: cf-context\ncurrent-context: cf-context\nusers:\n- name: warp-user\n  user:\n    # No auth needed here; WARP handles the Session identity at \n    # the transport layer and the Worker maps your Access identity\n    # to Kubernetes RBAC.\n    token: \"unused\"\n```\n\n**The Authentication Flow:**\n1.  Run your first command (e.g., `kubectl get pods`).\n2.  **The request will likely hang or fail.** This is normal.\n3.  Check your device for a **Cloudflare WARP push notification** (or open the\n    WARP client manually). You will be prompted to re-authenticate with your\n    Identity Provider (IdP) to prove your identity.\n4.  Once you successfully log in via your browser, the WARP session is\n    established.\n5.  **Re-run the command.** It will now succeed.\n\n*Note: You will only need to repeat this re-authentication step when your WARP\nsession expires, based on the session duration configured in your Zero Trust\ndashboard.*\n\n## 📊 Logging \u0026 Observability\n\nFor debugging and auditing purposes, you can configure the Worker to emit\ndetailed logs. This configuration is controlled by two variables in your\n`wrangler.toml`.\n\n### Configuration\n\nBy default, the Worker is configured for production safety: logging is set to\n`info` and explicit Kubernetes request tracing is **disabled**.\n\n```toml\n# wrangler.toml\n\n[vars]\n# 1. Master toggle for K8s Audit Logs (Default: \"false\")\n# If \"true\", logs details about every K8s request (Method, URL, Impersonated User, etc.).\n# Requires LOG_LEVEL to be \"info\" or \"debug\".\nENABLE_K8S_LOGGING = \"false\"\n\n# 2. Verbosity Level (Default: \"info\")\n# Options: \"debug\" \u003e \"info\" \u003e \"warn\" \u003e \"error\"\n# Setting this to \"info\" will log Info, Warn, and Error messages, but suppress Debug.\nLOG_LEVEL = \"info\"\n```\n\n### `LOG_LEVEL`\n\nThe `LOG_LEVEL` follows standard logging verbosity.\n\n* **`debug`**: Highest verbosity. Logs everything, including potentially\n  sensitive data.\n* **`info`**: Standard operational logs. **Required** if you want to see the\n  output from `ENABLE_K8S_LOGGING`.\n* **`warn`** / **`error`**: Only logs issues and failures.\n\n**Note:** If you set `ENABLE_K8S_LOGGING = \"true\"` but leave `LOG_LEVEL =\n\"error\"`, you will **not** see the k8s audit logs because they are emitted at\nthe `info` level.\n\n\u003e **⚠️ Security Warning: Sensitive Data**\n\u003e\n\u003eBe extremely careful when increasing log verbosity in a production environment:\n\u003e\n\u003e1. **`ENABLE_K8S_LOGGING = \"true\"`**: This exposes the **exact resource paths**\n\u003e   (`/api/v1/secrets`) and **user identities** (e.g., `User: alice`, `Groups: system:masters`)\n\u003e   being impersonated. This is sensitive audit data.\n\u003e2. **`LOG_LEVEL = \"debug\"`**: This may dump raw request headers, internal logic\n\u003e   states, or payload fragments.\n\u003e\n\u003eEnsure you treat these logs as sensitive data. We recommend sanitizing them or\n\u003eusing secure destinations if you are piping them to external systems.\n\n### Enterprise Analytics (Logpush)\n\nFor production environments, we strongly recommend enabling **Cloudflare\nLogpush**. This allows you to stream your Worker's logs to a persistent storage\ndestination (like **Cloudflare R2**, S3, Datadog, or Splunk) for long-term\nretention and security analysis.\n\n* **Setup:** Go to your Cloudflare Dashboard \u003e Analytics \u0026 Logs \u003e Logpush.\n* **Destinations:** We recommend using [Cloudflare R2](https://developers.cloudflare.com/r2/) for a cost-effective, S3-compatible storage solution.\n* **Documentation:** [Read the full Logpush guide](https://developers.cloudflare.com/logs/about/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudflare%2Fkubernetes-access-worker-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudflare%2Fkubernetes-access-worker-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudflare%2Fkubernetes-access-worker-example/lists"}