# Authorization

> Details of Kubernetes authorization mechanisms and supported authorization modes.

---

LLMS index: [llms.txt](/llms.txt)

---

<!-- overview -->

Kubernetes authorization takes place following
[authentication](/docs/reference/access-authn-authz/authentication/).
Usually, a client making a request must be authenticated (logged in) before its
request can be allowed; however, Kubernetes also allows anonymous requests in
some circumstances.

For an overview of how authorization fits into the wider context of API access
control, read
[Controlling Access to the Kubernetes API](/docs/concepts/security/controlling-access/).

<!-- body -->

## Authorization verdicts {#determine-whether-a-request-is-allowed-or-denied}

Kubernetes authorization of API requests takes place within the API server.
The API server evaluates all of the request attributes against all policies,
potentially also consulting external services, and then allows or denies the
request.

All parts of an API request must be allowed by some authorization
mechanism in order to proceed. In other words: access is denied by default.


<div class="alert alert-info" role="note"><h4 class="alert-heading">Note:</h4><p>Access controls and policies that
depend on specific fields of specific kinds of objects are handled by
<a class='glossary-tooltip' title='A piece of code that intercepts requests to the Kubernetes API server prior to persistence of the object.' data-bs-toggle='tooltip' data-bs-placement='top' href='/docs/reference/access-authn-authz/admission-controllers/' target='_blank' aria-label='admission controllers'>admission controllers</a>.</p>
<p>Kubernetes admission control happens after authorization has completed (and,
therefore, only when the authorization decision was to allow the request).</p>
</div>


When multiple [authorization modules](#authorization-modules) are configured,
each is checked in sequence.
If any authorizer _approves_ or _denies_ a request, that decision is immediately
returned and no other authorizer is consulted. If all modules have _no opinion_
on the request, then the request is denied. An overall deny verdict means that
the API server rejects the request and responds with an HTTP 403 (Forbidden)
status.

## Request attributes used in authorization

Kubernetes reviews only the following API request attributes:

 * **user** - The `user` string provided during authentication.
 * **group** - The list of group names to which the authenticated user belongs.
 * **extra** - A map of arbitrary string keys to string values, provided by the authentication layer.
 * **API** - Indicates whether the request is for an API resource.
 * **Request path** - Path to miscellaneous non-resource endpoints like `/api` or `/healthz`.
 * **API request verb** - API verbs like `get`, `list`, `create`, `update`, `patch`, `watch`, `delete`, and `deletecollection` are used for resource requests. To determine the request verb for a resource API endpoint, see [request verbs and authorization](/docs/reference/access-authn-authz/authorization/#determine-the-request-verb).
 * **HTTP request verb** - Lowercased HTTP methods like `get`, `post`, `put`, and `delete` are used for non-resource requests.
 * **Resource** - The ID or name of the resource that is being accessed (for resource requests only) -- For resource requests using `get`, `update`, `patch`, and `delete` verbs, you must provide the resource name.
 * **Subresource** - The subresource that is being accessed (for resource requests only). This can be a standard subresource (for example, `status` or `scale`) or a synthetic subresource used for fine-grained authorization.
 * **Namespace** - The namespace of the object that is being accessed (for namespaced resource requests only).
 * **API group** - The <a class='glossary-tooltip' title='A set of related paths in the Kubernetes API.' data-bs-toggle='tooltip' data-bs-placement='top' href='/docs/concepts/overview/kubernetes-api/#api-groups-and-versioning' target='_blank' aria-label='API Group'>API Group</a> being accessed (for resource requests only). An empty string designates the _core_ [API group](/docs/reference/using-api/#api-groups).

### Request verbs and authorization {#determine-the-request-verb}

#### Non-resource requests {#request-verb-non-resource}

Requests to endpoints other than `/api/v1/...` or `/apis/<group>/<version>/...`
are considered _non-resource requests_, and use the lower-cased HTTP method of the request as the verb.
For example, making a `GET` request using HTTP to endpoints such as `/api` or `/healthz` would use **get** as the verb.

#### Resource requests {#request-verb-resource}

To determine the request verb for a resource API endpoint, Kubernetes maps the HTTP verb
used and considers whether or not the request acts on an individual resource or on a
collection of resources:

HTTP verb     | request verb
--------------|---------------
`POST`        | **create**
`GET`, `HEAD` | **get** (for individual resources), **list** (for collections, including full object content), **watch** (for watching an individual resource or collection of resources)
`PUT`         | **update**
`PATCH`       | **patch**
`DELETE`      | **delete** (for individual resources), **deletecollection** (for collections)

<div class="alert alert-caution" role="note"><h4 class="alert-heading">Caution:</h4>+The <strong>get</strong>, <strong>list</strong> and <strong>watch</strong> verbs can all return the full details of a resource. In
terms of access to the returned data they are equivalent. For example, <strong>list</strong> on <code>secrets</code>
will reveal the <strong>data</strong> attributes of any returned resources.</div>


Kubernetes sometimes checks authorization for additional permissions using specialized verbs. For example:

* Special cases of [authentication](/docs/reference/access-authn-authz/authentication/)
  * **impersonate** verb on `users`, `groups`, and `serviceaccounts` in the core API group, and the `userextras` in the `authentication.k8s.io` API group.
* [Authorization of CertificateSigningRequests](/docs/reference/access-authn-authz/certificate-signing-requests/#authorization)
  * **approve** verb for CertificateSigningRequests, and **update** for revisions to existing approvals
* [RBAC](/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping)
  * **bind** and **escalate** verbs on `roles` and `clusterroles` resources in the `rbac.authorization.k8s.io` API group.
* [Dynamic Resource Allocation (DRA)](/docs/concepts/scheduling-eviction/dynamic-resource-allocation/)
  * Synthetic subresources such as `resourceclaims/binding` and `resourceclaims/driver` in the `resource.k8s.io` API group.
  * Node-aware verbs such as `associated-node:update`, `associated-node:patch`, `arbitrary-node:update`, and `arbitrary-node:patch` for DRA driver `resourceclaims/status` updates.

## Authorization context

Kubernetes expects attributes that are common to REST API requests. This means
that Kubernetes authorization works with existing organization-wide or
cloud-provider-wide access control systems which may handle other APIs besides
the Kubernetes API.

## Authorization modes {#authorization-modules}

The Kubernetes API server may authorize a request using one of several authorization modes:

`AlwaysAllow`
: This mode allows all requests, which brings [security risks](#warning-always-allow). Use this authorization mode only if you do not require authorization for your API requests (for example, for testing).

`AlwaysDeny`
: This mode blocks all requests. Use this authorization mode only for testing.

`ABAC` ([attribute-based access control](/docs/reference/access-authn-authz/abac/))
: Kubernetes ABAC mode defines an access control paradigm whereby access rights are granted to users through the use of policies which combine attributes together. The policies can use any type of attributes (user attributes, resource attributes, object, environment attributes, etc).

`RBAC` ([role-based access control](/docs/reference/access-authn-authz/rbac/))
: Kubernetes RBAC is a method of regulating access to computer or network resources based on the roles of individual users within an enterprise. In this context, access is the ability of an individual user to perform a specific task, such as view, create, or modify a file.  
  In this mode, Kubernetes uses the `rbac.authorization.k8s.io` API group to drive authorization decisions, allowing you to dynamically configure permission policies through the Kubernetes API.

`Node`
: A special-purpose authorization mode that grants permissions to kubelets based on the pods they are scheduled to run. To learn more about the Node authorization mode, see [Node Authorization](/docs/reference/access-authn-authz/node/).

`Webhook`
: Kubernetes [webhook mode](/docs/reference/access-authn-authz/webhook/) for authorization makes a synchronous HTTP callout, blocking the request until the remote HTTP service responds to the query.You can write your own software to handle the callout, or use solutions from the ecosystem.

<a id="warning-always-allow" />

<div class="alert alert-danger" role="note"><h4 class="alert-heading">Warning:</h4><p>Enabling the <code>AlwaysAllow</code> mode bypasses authorization; do not use this on a cluster where
you do not trust <strong>all</strong> potential API clients, including the workloads that you run.</p>
<p>Authorization mechanisms typically return either a <em>deny</em> or <em>no opinion</em> result; see
<a href="#determine-whether-a-request-is-allowed-or-denied">authorization verdicts</a> for more on this.
Activating the <code>AlwaysAllow</code> means that if all other authorizers return “no opinion”,
the request is allowed. For example, <code>--authorization-mode=AlwaysAllow,RBAC</code> has the
same effect as <code>--authorization-mode=AlwaysAllow</code> because Kubernetes RBAC does not
provide negative (deny) access rules.</p>
<p>You should not use the <code>AlwaysAllow</code> mode on a Kubernetes cluster where the API server
is reachable from the public internet.</p>
</div>


### The system:masters group

The `system:masters` group is a built-in Kubernetes group that grants unrestricted
access to the API server. Any user assigned to this group has full cluster administrator
privileges, bypassing any authorization restrictions imposed by the RBAC or Webhook mechanisms.
[Avoid adding users](/docs/concepts/security/rbac-good-practices/#least-privilege)
to this group. If you do need to grant a user cluster-admin rights, you can create a
[ClusterRoleBinding](/docs/reference/access-authn-authz/rbac/#user-facing-roles)
to the built-in `cluster-admin` ClusterRole.

### Authorization mode configuration {#choice-of-authz-config}

You can configure the Kubernetes API server's authorizer chain using either
a [configuration file](#using-configuration-file-for-authorization) only or
[command line arguments](#using-flags-for-your-authorization-module).

You have to pick one of the two configuration approaches; setting both `--authorization-config`
path and configuring an authorization webhook using the `--authorization-mode` and
`--authorization-webhook-*` command line arguments is not allowed.
If you try this, the API server reports an error message during startup, then exits immediately.

<!-- keep legacy hyperlinks working -->
<a id="configuring-the-api-server-using-an-authorization-config-file" />

### Configuring the API Server using an authorization config file {#using-configuration-file-for-authorization}








  <div class="feature-state-notice feature-stable" title="Feature Gate: StructuredAuthorizationConfiguration">
              <span class="feature-state-name">FEATURE STATE:</span> 
              <code>Kubernetes v1.32 [stable]</code>(enabled by default)</div>


Kubernetes lets you configure authorization chains that can include multiple
webhooks. The authorization items in that chain can have well-defined parameters that validate
requests in a particular order, offering you fine-grained control, such as explicit Deny on failures.

The configuration file approach even allows you to specify
[CEL](/docs/reference/using-api/cel/) rules to pre-filter requests before they are dispatched
to webhooks, helping you to prevent unnecessary invocations. The API server also automatically
reloads the authorizer chain when the configuration file is modified.

You specify the path to the authorization configuration using the
`--authorization-config` command line argument.

If you want to use command line arguments instead of a configuration file, that's also a valid and supported approach.
Some authorization capabilities (for example: multiple webhooks, webhook failure policy, and pre-filter rules)
are only available if you use an authorization configuration file.

#### Example configuration {#authz-config-example}

<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="c">#</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="c"># DO NOT USE THE CONFIG AS IS. THIS IS AN EXAMPLE.</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="c">#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">apiserver.config.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">AuthorizationConfiguration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">authorizers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">Webhook</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># Name used to describe the authorizer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># This is explicitly used in monitoring machinery for metrics</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># Note:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c">#   - Validation for this field is similar to how K8s labels are validated today.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># Required, with no default</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">webhook</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">webhook</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># The duration to cache &#39;authorized&#39; responses from the webhook</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># authorizer.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Same as setting `--authorization-webhook-cache-authorized-ttl` flag</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Default: 5m0s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">authorizedTTL</span><span class="p">:</span><span class="w"> </span><span class="l">30s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># If set to false, &#39;authorized&#39; responses from the webhook are not cached</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># and the specified authorizedTTL is ignored/has no effect.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Same as setting `--authorization-webhook-cache-authorized-ttl` flag to `0`.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Note: Setting authorizedTTL to `0` results in its default value being used.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Default: true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">cacheAuthorizedRequests</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># The duration to cache &#39;unauthorized&#39; responses from the webhook</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># authorizer.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Default: 30s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">unauthorizedTTL</span><span class="p">:</span><span class="w"> </span><span class="l">30s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># If set to false, &#39;unauthorized&#39; responses from the webhook are not cached</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># and the specified unauthorizedTTL is ignored/has no effect.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag to `0`.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Note: Setting unauthorizedTTL to `0` results in its default value being used.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Default: true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">cacheUnauthorizedRequests</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Timeout for the webhook request</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Maximum allowed is 30s.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Required, with no default.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># The API version of the authorization.k8s.io SubjectAccessReview to</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># send to and expect from the webhook.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Same as setting `--authorization-webhook-version` flag</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Required, with no default</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Valid values: v1beta1, v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">subjectAccessReviewVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># MatchConditionSubjectAccessReviewVersion specifies the SubjectAccessReview</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># version the CEL expressions are evaluated against</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Valid values: v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Required, no default value</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">matchConditionSubjectAccessReviewVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Controls the authorization decision when a webhook request fails to</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># complete or returns a malformed response or errors evaluating</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># matchConditions.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Valid values:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c">#   - NoOpinion: continue to subsequent authorizers to see if one of</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c">#     them allows the request</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c">#   - Deny: reject the request without consulting subsequent authorizers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Required, with no default.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">failurePolicy</span><span class="p">:</span><span class="w"> </span><span class="l">Deny</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">connectionInfo</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># Controls how the webhook should communicate with the server.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># Valid values:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># - KubeConfigFile: use the file specified in kubeConfigFile to locate the</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#   server.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># - InClusterConfig: use the in-cluster configuration to call the</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#   SubjectAccessReview API hosted by kube-apiserver. This mode is not</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#   allowed for kube-apiserver.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">KubeConfigFile</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># Path to KubeConfigFile for connection info</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># Required, if connectionInfo.Type is KubeConfigFile</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">kubeConfigFile</span><span class="p">:</span><span class="w"> </span><span class="l">/kube-system-authz-webhook.yaml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># matchConditions is a list of conditions that must be met for a request to be sent to this</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># webhook. An empty list of matchConditions matches all requests.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># There are a maximum of 64 match conditions allowed.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># The exact matching logic is (in order):</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#   1. If at least one matchCondition evaluates to FALSE, then the webhook is skipped.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#   2. If ALL matchConditions evaluate to TRUE, then the webhook is called.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#   3. If at least one matchCondition evaluates to an error (but none are FALSE):</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#      - If failurePolicy=Deny, then the webhook rejects the request</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c">#      - If failurePolicy=NoOpinion, then the error is ignored and the webhook is skipped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">matchConditions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># expression represents the expression which will be evaluated by CEL. Must evaluate to bool.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># CEL expressions have access to the contents of the SubjectAccessReview in v1 version.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># If version specified by subjectAccessReviewVersion in the request variable is v1beta1,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># the contents would be converted to the v1 version before evaluating the CEL expression.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c">#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c">#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># only send resource requests to the webhook</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">expression</span><span class="p">:</span><span class="w"> </span><span class="l">has(request.resourceAttributes)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># only intercept requests to kube-system</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">expression</span><span class="p">:</span><span class="w"> </span><span class="l">request.resourceAttributes.namespace == &#39;kube-system&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># don&#39;t intercept requests from kube-system service accounts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">expression</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;!(&#39;system:serviceaccounts:kube-system&#39; in request.groups)&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">Node</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">node</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">RBAC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">rbac</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">Webhook</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">in-cluster-authorizer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">webhook</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">authorizedTTL</span><span class="p">:</span><span class="w"> </span><span class="l">5m</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">unauthorizedTTL</span><span class="p">:</span><span class="w"> </span><span class="l">30s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">subjectAccessReviewVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">failurePolicy</span><span class="p">:</span><span class="w"> </span><span class="l">NoOpinion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">connectionInfo</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">InClusterConfig</span></span></span></code></pre></div>

When configuring the authorizer chain using a configuration file, make sure all the
control plane nodes have the same file contents. Take a note of the API server
configuration when upgrading / downgrading your clusters. For example, if upgrading
from Kubernetes 1.35 to Kubernetes 1.36,
you would need to make sure the config file is in a format that Kubernetes 1.36
can understand, before you upgrade the cluster. If you downgrade to 1.35,
you would need to set the configuration appropriately.

#### Authorization configuration and reloads

Kubernetes reloads the authorization configuration file when the API server observes a change
to the file, and also on a 60 second schedule if no change events were observed.


<div class="alert alert-info" role="note"><h4 class="alert-heading">Note:</h4><p>You must ensure that all non-webhook authorizer types remain unchanged in the file on reload.</p>
<p>A reload <strong>must not</strong> add or remove Node or RBAC authorizers (they can be reordered,
but cannot be added or removed).</p>
</div>


### Command line authorization mode configuration {#using-flags-for-your-authorization-module}

You can use the following modes:

* `--authorization-mode=ABAC` (Attribute-based access control mode)
* `--authorization-mode=RBAC` (Role-based access control mode)
* `--authorization-mode=Node` (Node authorizer)
* `--authorization-mode=Webhook` (Webhook authorization mode)
* `--authorization-mode=AlwaysAllow` (always allows requests; carries [security risks](#warning-always-allow))
* `--authorization-mode=AlwaysDeny` (always denies requests)

You can choose more than one authorization mode; for example:
`--authorization-mode=Node,RBAC,Webhook`

Kubernetes checks authorization modules based on the order that you specify them
on the API server's command line, so an earlier module has higher priority to allow
or deny a request.

You cannot combine the `--authorization-mode` command line argument with the
`--authorization-config` command line argument used for
[configuring authorization using a local file](#using-configuration-file-for-authorization-mode).

For more information on command line arguments to the API server, read the
[`kube-apiserver` reference](/docs/reference/command-line-tools-reference/kube-apiserver/).

## Privilege escalation via workload creation or edits {#privilege-escalation-via-pod-creation}

Users who can create/edit pods in a namespace, either directly or through an object that
enables indirect [workload management](/docs/concepts/architecture/controller/), may be
able to escalate their privileges in that namespace. The potential routes to privilege
escalation include Kubernetes [API extensions](/docs/concepts/extend-kubernetes/#api-extensions)
and their associated <a class='glossary-tooltip' title='A control loop that watches the shared state of the cluster through the apiserver and makes changes attempting to move the current state towards the desired state.' data-bs-toggle='tooltip' data-bs-placement='top' href='/docs/concepts/architecture/controller/' target='_blank' aria-label='controllers'>controllers</a>.

<div class="alert alert-caution" role="note"><h4 class="alert-heading">Caution:</h4>As a cluster administrator, use caution when granting access to create or edit workloads.
Some details of how these can be misused are documented in
<a href="/docs/reference/access-authn-authz/authorization/#escalation-paths">escalation paths</a>.</div>


### Escalation paths {#escalation-paths}

There are different ways that an attacker or untrustworthy user could gain additional
privilege within a namespace, if you allow them to run arbitrary Pods in that namespace:

- Mounting arbitrary Secrets in that namespace
  - Can be used to access confidential information meant for other workloads
  - Can be used to obtain a more privileged ServiceAccount's service account token
- Using arbitrary ServiceAccounts in that namespace
  - Can perform Kubernetes API actions as another workload (impersonation)
  - Can perform any privileged actions that ServiceAccount has
- Mounting or using ConfigMaps meant for other workloads in that namespace
  - Can be used to obtain information meant for other workloads, such as database host names.
- Mounting volumes meant for other workloads in that namespace
  - Can be used to obtain information meant for other workloads, and change it.

<div class="alert alert-caution" role="note"><h4 class="alert-heading">Caution:</h4>As a system administrator, you should be cautious when deploying CustomResourceDefinitions
that let users make changes to the above areas. These may open privilege escalations paths.
Consider the consequences of this kind of change when deciding on your authorization controls.</div>


## Checking API access

`kubectl` provides the `auth can-i` subcommand for quickly querying the API authorization layer.
The command uses the `SelfSubjectAccessReview` API to determine if the current user can perform
a given action, and works regardless of the authorization mode used.


```bash
kubectl auth can-i create deployments --namespace dev
```

The output is similar to this:

```
yes
```

```shell
kubectl auth can-i create deployments --namespace prod
```

The output is similar to this:

```
no
```

Administrators can combine this with [user impersonation](/docs/reference/access-authn-authz/authentication/#user-impersonation)
to determine what action other users can perform.

```bash
kubectl auth can-i list secrets --namespace dev --as dave
```

The output is similar to this:

```
no
```

Similarly, to check whether a ServiceAccount named `dev-sa` in Namespace `dev`
can list Pods in the Namespace `target`:

```bash
kubectl auth can-i list pods \
    --namespace target \
    --as system:serviceaccount:dev:dev-sa
```

The output is similar to this:

```
yes
```

SelfSubjectAccessReview is part of the `authorization.k8s.io` API group, which
exposes the API server authorization to external services. Other resources in
this group include:

SubjectAccessReview
: Access review for any user, not only the current one. Useful for delegating authorization decisions to the API server. For example, the kubelet and extension API servers use this to determine user access to their own APIs.

LocalSubjectAccessReview
: Like SubjectAccessReview but restricted to a specific namespace.

SelfSubjectRulesReview
: A review which returns the set of actions a user can perform within a namespace. Useful for users to quickly summarize their own access, or for UIs to hide/show actions.

These APIs can be queried by creating normal Kubernetes resources, where the response `status`
field of the returned object is the result of the query. For example:

```bash
kubectl create -f - -o yaml << EOF
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
spec:
  resourceAttributes:
    group: apps
    resource: deployments
    verb: create
    namespace: dev
EOF
```

The generated SelfSubjectAccessReview is similar to:

<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">authorization.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">SelfSubjectAccessReview</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">creationTimestamp</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">resourceAttributes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">group</span><span class="p">:</span><span class="w"> </span><span class="l">apps</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">resource</span><span class="p">:</span><span class="w"> </span><span class="l">deployments</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l">dev</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">verb</span><span class="p">:</span><span class="w"> </span><span class="l">create</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="nt">status</span><span class="p">:</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">  </span><span class="nt">allowed</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">  </span><span class="nt">denied</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span></span></span></code></pre></div>

## What's next

* To learn more about Authentication, see [Authentication](/docs/reference/access-authn-authz/authentication/).
* For an overview, read [Controlling Access to the Kubernetes API](/docs/concepts/security/controlling-access/).
* To learn more about Admission Control, see [Using Admission Controllers](/docs/reference/access-authn-authz/admission-controllers/).
* Read more about [Common Expression Language in Kubernetes](/docs/reference/using-api/cel/).
