REST API — keystone — branch stable/2026.2
Branch
stable/2026.2@e6dc5ae079e6— repository https://opendev.org/openstack/keystone — analysed on 2026-10-28
The route table below was not read from the api-ref: it was extracted from the running Flask application (app.url_map of keystone.server.flask.application.application_factory). That gives 259 method + path pairs on 125 paths. The handler of each one is the real method (decorators unwrapped), and its policy rule comes from the operations declared by each default policy rule (keystone/common/policies/). HEAD is accepted wherever GET is, and is not listed.
1. Conventions shared by every endpoint
Request processing
- Pipeline (
keystone/server/flask/core.py:39-70, applied bykeystone/server/flask/core.py:93-142), in request order:ProxyFix(werkzeug);- oslo
CORS; RequestBodySizeLimiter;HTTPProxyToWSGI;- osprofiler;
RequestId;URLNormalizingMiddleware, which removes a trailing/(keystone/server/flask/request_processing/middleware/url_normalize.py:16);AuthContextMiddleware, which validatesX-Auth-Tokenand builds the request context (keystone/server/flask/request_processing/middleware/auth_context.py). Then the Flask application runsbefore_requestrequest logging and JSON body checks (keystone/server/flask/application.py:211-212).
- **
/healthcheck** is served by oslo.middleware's healthcheck application, mounted next to Flask (keystone/server/flask/application.py:228-237). - Body: on POST, PUT and PATCH, a body that is not JSON is rejected with 400 (
keystone/server/flask/request_processing/json_body.py:23). Exceptions areapplication/x-www-form-urlencodedon/v3/OS-OAUTH2/token, and the federation protocol endpoints, which receive SAML/OIDC posts. - Every response carries
Vary: X-Auth-Token(keystone/server/flask/application.py:106-110). A 204 has noContent-Type(keystone/server/flask/common.py:182). - No microversions: Keystone exposes a single
v3version. Discovery isGET /(300 Multiple Choices, the version list) andGET /v3(version document). Both answer in JSON Home when the client sendsAccept: application/json-home(keystone/api/discovery.py:44-65).
Authorisation
- Every handler must call
ENFORCER.enforce_call(action=...)or be marked@unenforced_api. Otherwise the request fails:_assert_rbac_enforcement_called(keystone/server/flask/common.py:160) turns a missing check into a 500. enforce_callfirst requires an authenticated context (401 otherwise,keystone/common/rbac_enforcer/enforcer.py:300-320). It then evaluates the oslo.policy rule with the token's roles and scope; a refusal is 403ForbiddenAction(keystone/common/rbac_enforcer/enforcer.py:102-136).- The default rules combine three ingredients (
keystone/common/policies/base.py:47-76):- the token's scope: system (
system_scope:all), domain or project; - the default roles
reader⊂member⊂admin, as implied roles created bykeystone-manage bootstrap; - ownership, for example
user_id:%(target.credential.user_id)s.
- the token's scope: system (
Lists
- Filters are query parameters named after an attribute, with optional comparators
__contains,__icontains,__startswith,__istartswith,__endswith,__iendswith, and__eq/__neq… where supported (keystone/server/flask/common.py:903-972). - Pagination:
limitandmarkerare bounded by[DEFAULT]/max_db_limitand by the per-driverlist_limit. When the list is cut, the response says so:"truncated": trueand alinks.nextURL with the nextmarker(keystone/server/flask/common.py:701-764). - Links: every entity has
links.self. Every collection haslinks.self,links.nextandlinks.previous.
Quirk: methods declared on a shared resource
Some resources serve the collection and the member with the same class, for example /v3/policies and /v3/OS-FEDERATION/mappings. Flask therefore lists the member methods on the collection path too, for example DELETE /v3/policies. Calling them there without an ID raises a TypeError, which the global handler turns into a **400 ValidationError** (keystone/server/flask/application.py:176-183), not a 405. A rewrite should answer 405, but must know that clients currently see 400.
2. Functional description by area
2.1 Authentication and tokens (/v3/auth/*)
**POST /v3/auth/tokens: issue a token.**
- Purpose: authenticate a user with one or more methods and obtain a token, unscoped or scoped to a project, a domain, the system, or a trust.
- Actor: anyone; the endpoint is not authenticated (
@unenforced_api). - Flow (
keystone/api/auth.py:320-336,keystone/api/_shared/authentication.py:208-282):- The
authbody is validated byvalidate_issue_token_auth. - If the WSGI server set
REMOTE_USER, theexternalmethod runs first. - Each method listed in
identity.methodsruns its plugin, chosen from[auth]/methods(defaultexternal, password, token, oauth1, mapped, application_credential, ec2credential,keystone/conf/constants.py:19-27). A plugin may answer "more steps needed": the response is then 401 with an auth receipt (MFA, see below). - Without an explicit scope, the user's
default_project_idis used, if the project and its domain are enabled and the user has a role on it. Otherwise the token is unscoped (keystone/api/_shared/authentication.py:34-117). - The user's MFA rules are checked. Missing methods give 401
InsufficientAuthMethods, with anOpenstack-Auth-Receiptheader. - The token is issued (
keystone/token/provider.py:276-390). Its expiry is[token]/expiration(default 3600 s), capped by the expiry of the trust or application credential in use. - A trust with
remaining_useshas one use consumed after issuance.
- The
- Response: 201 with the token ID in the
X-Subject-Tokenheader. The body holdstoken(user, methods, roles, scope,expires_at,issued_at,audit_ids, andcatalogunless?nocatalog). - Password method (
keystone/auth/plugins/password.py:24-44,keystone/identity/backends/sql.py:63-123). Checks run in this order:- locked account → 401
AccountLocked; - wrong password → failure counter +1 and 401 "Invalid username or password";
- disabled user → 401
UserDisabled; - expired password → 401
PasswordExpired. The lockout is driven by[security_compliance]/lockout_failure_attemptsandlockout_duration. A successful authentication resets the counter and updateslast_active_at.
- locked account → 401
- Auth receipts (MFA): when a user has MFA rules and only part of them is satisfied, the 401 carries a receipt. The client sends it back in
Openstack-Auth-Receiptwith the missing methods (keystone/receipt/handlers.py,keystone/server/flask/application.py:128-129).
**GET/HEAD /v3/auth/tokens: validate a token** (keystone/api/auth.py:279-317).
- The token to check is in
X-Subject-Token; the caller authenticates with its ownX-Auth-Token. Policy:identity:validate_token(GET) oridentity:check_token(HEAD). ?allow_expired=1accepts a token expired for less than[token]/allow_expired_window(default 2 days).?nocatalogdrops the catalog.- A token is valid when all these hold (
keystone/token/provider.py:139-275):- it decrypts with one of the Fernet keys (or verifies with a JWS key);
- it has not expired;
- it matches no revocation event;
- its user is still enabled;
- if it comes from an application credential with access rules, the caller sends
OpenStack-Identity-Access-Rules≥ 1.0.
- Every failure becomes **404
TokenNotFound**, never a 401: a stale token looks like a token that does not exist. - Side effect: validating a token whose user was disabled writes a revocation event for that user and empties the token cache (
keystone/token/provider.py:218-229).
**DELETE /v3/auth/tokens: revoke a token** (keystone/api/auth.py:338-357, keystone/token/provider.py:406-434).
- Writes a revocation event on the token's
audit_id. - By default (
?cascade=true), it also writes one on its chain (audit_chain_id), so the scoped tokens obtained from it are revoked too, and the whole token cache is emptied.?cascade=falselimits the revocation to that token.
**Other /v3/auth endpoints**: GET /v3/auth/catalog, /v3/auth/projects, /v3/auth/domains and /v3/auth/system list, for the caller's token, its catalog and the projects, domains or system scope it could rescope to (keystone/api/auth.py:119-260). GET /v3/auth/tokens/OS-PKI/revoked is a fossil: it answers 410 if [token]/revoke_by_id = false, 403 otherwise (keystone/api/auth.py:262-276).
2.2 Users, groups, passwords
- Users (
keystone/api/users.py,keystone/identity/core.py): CRUD within a domain.- The identity driver is chosen per domain: SQL, or LDAP when
[identity]/domain_specific_drivers_enabledpoints a domain to an LDAP configuration. - Users from LDAP or federation get a public ID computed in the
id_mappingtable (sha256 generator). default_project_idcannot be a domain (keystone/identity/core.py:1076-1093).- Disabling or deleting a user triggers, through internal callbacks: revocation of the user's tokens, deletion of their application credentials and of the trusts where they are trustee, and invalidation of the caches (see async processing).
- The identity driver is chosen per domain: SQL, or LDAP when
- Passwords (
POST /v3/users/{user_id}/password) is the self-service change. It is unauthenticated: the body carries the original password, which is checked. The rules come from[security_compliance]:password_regex;unique_last_password_count(password history);minimum_password_age;password_expires_days;change_password_upon_first_use. Breaking one of them gives 400PasswordValidationErrorand its variants (see errors).
- Groups: CRUD and membership (
/v3/groups/{group_id}/users/{user_id}). A user and a group from different backends cannot be linked (403CrossBackendNotAllowed). - **
DELETE /v3/users/{user_id}/tokens** revokes all of a user's tokens (policyidentity:revoke_tokens_for_user,keystone/api/users.py:949).
2.3 Projects, domains, tags, domain configuration
- Projects form a tree (
parent_id). A domain is a root project withis_domain = true. The rules (keystone/resource/core.py:62-620):- Hierarchy:
- maximum depth
[DEFAULT]/max_project_tree_depth, or less if the limit model requires it (403); - a project's domain must be the domain of its parent (400);
- no creation under a disabled project (400);
parent_idandis_domaincannot be changed (403 and 400).
- maximum depth
- Names: a name is unique within a domain (409). With
[resource]/project_name_url_safeset, a name with reserved URL characters is refused (400). - Disabling: a project with enabled children cannot be disabled (403), unless
?cascade. In that case onlyenabledcan change (400 otherwise). - Deleting: only a leaf can be deleted, unless
?cascade, which requires the whole subtree to be disabled (403). Deleting a project removes its assignments, credentials, trusts and limits (keystone/resource/core.py:521-539). - Immutable resources: a project, domain or role with the
immutableoption refuses updates and deletion (403ResourceUpdateForbidden/ResourceDeleteForbidden).
- Hierarchy:
- Domains: an enabled domain cannot be deleted. Deleting a domain removes its projects, users, groups, assignments and federated identity providers (internal callbacks).
- Tags:
/v3/projects/{id}/tags[/{tag}], and filterstags,tags-any,not-tags,not-tags-anyonGET /v3/projects. - Domain configuration (
/v3/domains/{id}/config[...]): per-domain identity settings (an LDAP driver per domain). Only whitelisted options are allowed; sensitive ones (passwords) are stored apart and never returned (keystone/resource/core.py:1226-1600).
2.4 Roles, implied roles, assignments
- Roles are global, or domain-specific (
domain_id). A domain-specific role can only be assigned in its domain (403DomainSpecificRoleMismatch). - Implied roles (
/v3/roles/{prior}/implies/{implied}): a role brings others when the token is computed. The default chain isadmin→member→reader. Some roles cannot be implied:[assignment]/prohibited_implied_role,adminby default (403InvalidImpliedRole). - Assignments (grants): user or group × role × project, domain or system.
OS-INHERITassignments are inherited by every project under a domain or project. - **
GET /v3/role_assignments** lists them, with?effective(groups expanded, inheritance and implied roles applied),?include_namesand?include_subtree. Effective assignments are cached in thecomputed assignmentsregion, invalidated on every change.
2.5 Catalog, endpoint filtering, endpoint policies
- Regions (tree, cycles refused with 400
CircularRegionHierarchyError), services and endpoints (interface= public/internal/admin, URL validated). These build the catalog returned in tokens. - OS-EP-FILTER: associates endpoints or endpoint groups with projects, to restrict the catalog of a project-scoped token. It needs
[catalog]/driver = sqland[endpoint_filter]. - OS-ENDPOINT-POLICY and
/v3/policies: store opaque blobs (old policy files) and associate them with endpoints, services or regions. These APIs are deprecated since Queens (keystone/api/policy.py:76-96).
2.6 Credentials, EC2 and S3
- **
/v3/credentials: blobs belonging to a user, **encrypted with the credential Fernet keys ([credential]/key_repository). The ID of an EC2 credential issha256(access). The number per user is capped by[credential]/user_limit(403). - Security fix on this branch (see 06): the
trust_id,app_cred_idandaccess_token_idfields of an EC2 blob are now server-managed (keystone/api/credentials.py:144-170). Any client-supplied value is stripped, and only the context of the token used is written. - **
POST /v3/ec2tokens** and **POST /v3/s3tokens** exchange an AWS-style signature for a Keystone token (keystone/api/_shared/EC2_S3_Resource.py). They check:- the signature (
_check_signature); - the timestamp: a signed request older than
[credential]/auth_ttlis refused (keystone/api/_shared/EC2_S3_Resource.py:46-68); - since this branch, that the credential's owner is a party to the referenced trust, or owns the application credential or the OAuth1 access token (
keystone/api/_shared/EC2_S3_Resource.py:166-220).GETon these two paths answers 405.
- the signature (
2.7 Application credentials and access rules
- A user creates a credential for one project with a subset of their roles (
keystone/application_credential/core.py:87-150), with optionalexpires_at,unrestrictedandaccess_rules(service, path, method).- The secret is generated if not given, returned once only, and stored hashed.
- Requesting a role the user does not have gives 404
RoleAssignmentNotFound. - The number per user is capped (
[application_credential]/user_limit, 403).
- Effects elsewhere: a token obtained with an application credential:
- expires no later than the credential;
- carries only the credential's roles;
- cannot create other credentials or trusts, unless
unrestricted. Disabling or deleting the user, or removing their role on the project, deletes their application credentials (callbacks).
2.8 Trusts (OS-TRUST)
- A trustor delegates roles on a project to a trustee, possibly with impersonation, an expiry,
remaining_usesand re-delegation (keystone/trust/core.py:57-205). - Re-delegation rules (403):
- depth within
[trust]/max_redelegation_count; - no
remaining_useson a re-delegated trust; - expiry within the parent's;
- roles a subset of the parent's;
- no impersonation if the parent has none.
- depth within
remaining_usesmust be positive (400).- Deleting the trustee deletes their trusts. An exhausted trust gives 403
TrustUseLimitReached.
2.9 Federation (OS-FEDERATION)
- Configuration:
- identity providers (
remote_ids; maximum length 255 since this branch, see 06); - protocols (
saml2,openid,mapped…); - mappings: JSON rules that turn the assertion's attributes into a user, groups and projects (
keystone/federation/utils.py:469-1130); - service providers (Keystone-to-Keystone).
- identity providers (
- Authentication:
GET/POST /v3/OS-FEDERATION/identity_providers/{idp}/protocols/{protocol}/auth(and the WebSSO variants).- The web server (mod_shib, mod_auth_openidc) has already validated the assertion. Keystone reads the attributes from the WSGI environment and applies the mapping.
- It creates or updates a shadow user (
federated_user,nonlocal_user) and expiring group memberships (expiring_user_group_membership, TTLauthorization_ttl). - It returns an unscoped federated token (
keystone/auth/plugins/mapped.py:41-500).
- Keystone as IdP:
POST /v3/auth/OS-FEDERATION/saml2[/ecp]produces a SAML assertion **signed by thexmlsec1binary** (keystone/federation/idp.py:447-541).GET /v3/OS-FEDERATION/saml2/metadatapublishes the metadata.
2.10 OAuth 1.0a and OAuth 2.0
- OAuth1 (deprecated): consumers, request token, authorisation by a user, access token, then an
oauth1token. - OAuth2 (
POST /v3/OS-OAUTH2/token,keystone/api/os_oauth2.py:74-130):- grant
client_credentialsonly (400 otherwise); - the client authenticates either with an application credential (
client_secret_basic) or with a client certificate (tls_client_auth, mTLS); - in the mTLS case, the token carries the certificate thumbprint, which keystonemiddleware checks.
- Errors follow RFC 6749 (
{"error": "invalid_client", ...},keystone/oauth2/handlers.py). The other methods answer 405.
- grant
2.11 Unified limits
- Registered limits are a default per service, region and resource name. Limits override them per project or domain.
- The model (
[unified_limit]/enforcement_model:flatorstrict_two_level,GET /v3/limits/model) checks consistency: instrict_two_level, children cannot exceed their parent, and the tree is limited to 2 levels (403InvalidLimit). - A registered limit that is referenced cannot be modified (403
RegisteredLimitError).
2.12 Revocation events and certificates
GET /v3/OS-REVOKE/events[?since=]lists the revocation events (policyidentity:list_revoke_events).OS-SIMPLE-CERTis deprecated: it answers 410 (keystone/api/os_simple_cert.py).
3. Route table (extracted from the application)
Handler: the method that serves the call. Policy rule: the default rule that enforce_call evaluates (rules and check strings in _rewrite/policies_stable-2026.2.json). "none (unauthenticated)": an @unenforced_api handler. "—": no documented rule; the handler either checks nothing beyond authentication, or answers 405 or 410.
Discovery (3 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | / | keystone/api/discovery.py:56 | — |
| GET | /static/{filename} | Flask built-in static route | — |
| GET | /v3 | keystone/api/discovery.py:87 | — |
Authentication and tokens (8 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/auth/catalog | keystone/api/auth.py:237 | identity:get_auth_catalog |
| GET | /v3/auth/domains | keystone/api/auth.py:157 | identity:get_auth_domains, identity:list_domains_for_user |
| GET | /v3/auth/projects | keystone/api/auth.py:123 | identity:get_auth_projects |
| GET | /v3/auth/system | keystone/api/auth.py:189 | identity:get_auth_system |
| DELETE | /v3/auth/tokens | keystone/api/auth.py:338 | identity:revoke_token |
| GET | /v3/auth/tokens | keystone/api/auth.py:279 | identity:check_token, identity:validate_token |
| POST | /v3/auth/tokens | keystone/api/auth.py:319 | none (unauthenticated) |
| GET | /v3/auth/tokens/OS-PKI/revoked | keystone/api/auth.py:263 | identity:revocation_list |
Federation (36 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/OS-FEDERATION/domains | keystone/api/auth.py:157 | identity:get_auth_domains |
| GET | /v3/OS-FEDERATION/identity_providers | keystone/api/os_federation.py:112 | identity:list_identity_providers |
| DELETE | /v3/OS-FEDERATION/identity_providers/{idp_id} | keystone/api/os_federation.py:194 | identity:delete_identity_provider |
| GET | /v3/OS-FEDERATION/identity_providers/{idp_id} | keystone/api/os_federation.py:154 | identity:get_identity_provider |
| PATCH | /v3/OS-FEDERATION/identity_providers/{idp_id} | keystone/api/os_federation.py:183 | identity:update_identity_provider |
| PUT | /v3/OS-FEDERATION/identity_providers/{idp_id} | keystone/api/os_federation.py:167 | identity:create_identity_provider |
| GET | /v3/OS-FEDERATION/identity_providers/{idp_id}/protocols | keystone/api/os_federation.py:225 | identity:list_protocols |
| DELETE | /v3/OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id} | keystone/api/os_federation.py:285 | identity:delete_protocol |
| GET | /v3/OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id} | keystone/api/os_federation.py:243 | identity:get_protocol |
| PATCH | /v3/OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id} | keystone/api/os_federation.py:270 | identity:update_protocol |
| PUT | /v3/OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id} | keystone/api/os_federation.py:255 | identity:create_protocol |
| GET | /v3/OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id}/auth | keystone/api/os_federation.py:518 | none (unauthenticated) |
| POST | /v3/OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id}/auth | keystone/api/os_federation.py:527 | none (unauthenticated) |
| DELETE | /v3/OS-FEDERATION/mappings | keystone/api/os_federation.py:379 | identity:delete_mapping |
| GET | /v3/OS-FEDERATION/mappings | keystone/api/os_federation.py:303 | identity:list_mappings |
| PATCH | /v3/OS-FEDERATION/mappings | keystone/api/os_federation.py:367 | identity:update_mapping |
| PUT | /v3/OS-FEDERATION/mappings | keystone/api/os_federation.py:353 | identity:create_mapping |
| DELETE | /v3/OS-FEDERATION/mappings/{mapping_id} | keystone/api/os_federation.py:379 | identity:delete_mapping |
| GET | /v3/OS-FEDERATION/mappings/{mapping_id} | keystone/api/os_federation.py:303 | identity:get_mapping |
| PATCH | /v3/OS-FEDERATION/mappings/{mapping_id} | keystone/api/os_federation.py:367 | identity:update_mapping |
| PUT | /v3/OS-FEDERATION/mappings/{mapping_id} | keystone/api/os_federation.py:353 | identity:create_mapping |
| GET | /v3/OS-FEDERATION/projects | keystone/api/auth.py:123 | identity:get_auth_projects |
| GET | /v3/OS-FEDERATION/saml2/metadata | keystone/api/os_federation.py:499 | none (unauthenticated) |
| GET | /v3/OS-FEDERATION/service_providers | keystone/api/os_federation.py:405 | identity:list_service_providers |
| DELETE | /v3/OS-FEDERATION/service_providers/{service_provider_id} | keystone/api/os_federation.py:488 | identity:delete_service_provider |
| GET | /v3/OS-FEDERATION/service_providers/{service_provider_id} | keystone/api/os_federation.py:444 | identity:get_service_provider |
| PATCH | /v3/OS-FEDERATION/service_providers/{service_provider_id} | keystone/api/os_federation.py:473 | identity:update_service_provider |
| PUT | /v3/OS-FEDERATION/service_providers/{service_provider_id} | keystone/api/os_federation.py:456 | identity:create_service_provider |
| GET | /v3/auth/OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id}/websso | keystone/api/auth.py:410 | none (unauthenticated) |
| POST | /v3/auth/OS-FEDERATION/identity_providers/{idp_id}/protocols/{protocol_id}/websso | keystone/api/auth.py:414 | none (unauthenticated) |
| GET | /v3/auth/OS-FEDERATION/saml2 | keystone/api/auth.py:420 | — |
| POST | /v3/auth/OS-FEDERATION/saml2 | keystone/api/auth.py:423 | none (unauthenticated) |
| GET | /v3/auth/OS-FEDERATION/saml2/ecp | keystone/api/auth.py:440 | — |
| POST | /v3/auth/OS-FEDERATION/saml2/ecp | keystone/api/auth.py:443 | none (unauthenticated) |
| GET | /v3/auth/OS-FEDERATION/websso/{protocol_id} | keystone/api/auth.py:391 | none (unauthenticated) |
| POST | /v3/auth/OS-FEDERATION/websso/{protocol_id} | keystone/api/auth.py:395 | none (unauthenticated) |
Users, groups and passwords (19 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/groups | keystone/api/groups.py:58 | identity:list_groups |
| POST | /v3/groups | keystone/api/groups.py:86 | identity:create_group |
| DELETE | /v3/groups/{group_id} | keystone/api/groups.py:147 | identity:delete_group |
| GET | /v3/groups/{group_id} | keystone/api/groups.py:114 | identity:get_group |
| PATCH | /v3/groups/{group_id} | keystone/api/groups.py:128 | identity:update_group |
| GET | /v3/groups/{group_id}/users | keystone/api/groups.py:163 | identity:list_users_in_group |
| DELETE | /v3/groups/{group_id}/users/{user_id} | keystone/api/groups.py:245 | identity:remove_user_from_group |
| GET | /v3/groups/{group_id}/users/{user_id} | keystone/api/groups.py:215 | identity:check_user_in_group |
| PUT | /v3/groups/{group_id}/users/{user_id} | keystone/api/groups.py:229 | identity:add_user_to_group |
| GET | /v3/users | keystone/api/users.py:294 | identity:list_users |
| POST | /v3/users | keystone/api/users.py:339 | identity:create_user |
| DELETE | /v3/users/{user_id} | keystone/api/users.py:269 | identity:delete_user |
| GET | /v3/users/{user_id} | keystone/api/users.py:234 | identity:get_user |
| PATCH | /v3/users/{user_id} | keystone/api/users.py:249 | identity:update_user |
| GET | /v3/users/{user_id}/groups | keystone/api/users.py:411 | identity:list_groups_for_user |
| GET | /v3/users/{user_id}/password | keystone/api/users.py:361 | none (unauthenticated) |
| POST | /v3/users/{user_id}/password | keystone/api/users.py:366 | none (unauthenticated) |
| GET | /v3/users/{user_id}/projects | keystone/api/users.py:392 | identity:list_user_projects |
| DELETE | /v3/users/{user_id}/tokens | keystone/api/users.py:949 | identity:revoke_tokens_for_user |
Application credentials and access rules (7 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/users/{user_id}/access_rules | keystone/api/users.py:874 | identity:list_access_rules |
| DELETE | /v3/users/{user_id}/access_rules/{access_rule_id} | keystone/api/users.py:926 | identity:delete_access_rule |
| GET | /v3/users/{user_id}/access_rules/{access_rule_id} | keystone/api/users.py:904 | identity:get_access_rule |
| GET | /v3/users/{user_id}/application_credentials | keystone/api/users.py:741 | identity:list_application_credentials |
| POST | /v3/users/{user_id}/application_credentials | keystone/api/users.py:763 | identity:create_application_credential |
| DELETE | /v3/users/{user_id}/application_credentials/{application_credential_id} | keystone/api/users.py:851 | identity:delete_application_credential |
| GET | /v3/users/{user_id}/application_credentials/{application_credential_id} | keystone/api/users.py:828 | identity:get_application_credential |
Credentials, EC2 and S3 (13 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/credentials | keystone/api/credentials.py:173 | identity:get_credential, identity:list_credentials |
| POST | /v3/credentials | keystone/api/credentials.py:217 | identity:create_credential |
| DELETE | /v3/credentials/{credential_id} | keystone/api/credentials.py:315 | identity:delete_credential |
| GET | /v3/credentials/{credential_id} | keystone/api/credentials.py:268 | identity:get_credential |
| PATCH | /v3/credentials/{credential_id} | keystone/api/credentials.py:287 | identity:update_credential |
| GET | /v3/ec2tokens | keystone/api/_shared/EC2_S3_Resource.py:34 | none (unauthenticated) |
| POST | /v3/ec2tokens | keystone/api/ec2tokens.py:64 | identity:ec2tokens_validate |
| GET | /v3/s3tokens | keystone/api/_shared/EC2_S3_Resource.py:34 | none (unauthenticated) |
| POST | /v3/s3tokens | keystone/api/s3tokens.py:102 | identity:s3tokens_validate |
| GET | /v3/users/{user_id}/credentials/OS-EC2 | keystone/api/users.py:456 | identity:ec2_list_credentials |
| POST | /v3/users/{user_id}/credentials/OS-EC2 | keystone/api/users.py:473 | identity:ec2_create_credential |
| DELETE | /v3/users/{user_id}/credentials/OS-EC2/{credential_id} | keystone/api/users.py:533 | identity:ec2_delete_credential |
| GET | /v3/users/{user_id}/credentials/OS-EC2/{credential_id} | keystone/api/users.py:516 | identity:ec2_get_credential |
Projects and domains (29 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/domains | keystone/api/domains.py:135 | identity:list_domains |
| POST | /v3/domains | keystone/api/domains.py:158 | identity:create_domain |
| DELETE | /v3/domains/{domain_id} | keystone/api/domains.py:116 | identity:delete_domain |
| GET | /v3/domains/{domain_id} | keystone/api/domains.py:87 | identity:get_domain |
| PATCH | /v3/domains/{domain_id} | keystone/api/domains.py:101 | identity:update_domain |
| DELETE | /v3/domains/{domain_id}/config | keystone/api/domains.py:245 | identity:delete_domain_config |
| GET | /v3/domains/{domain_id}/config | keystone/api/domains.py:190 | identity:get_domain_config |
| PATCH | /v3/domains/{domain_id}/config | keystone/api/domains.py:230 | identity:update_domain_config |
| PUT | /v3/domains/{domain_id}/config | keystone/api/domains.py:270 | identity:create_domain_config |
| DELETE | /v3/domains/{domain_id}/config/{group} | keystone/api/domains.py:245 | identity:delete_domain_config |
| GET | /v3/domains/{domain_id}/config/{group} | keystone/api/domains.py:190 | identity:get_domain_config |
| PATCH | /v3/domains/{domain_id}/config/{group} | keystone/api/domains.py:230 | identity:update_domain_config |
| DELETE | /v3/domains/{domain_id}/config/{group}/{option} | keystone/api/domains.py:245 | identity:delete_domain_config |
| GET | /v3/domains/{domain_id}/config/{group}/{option} | keystone/api/domains.py:190 | identity:get_domain_config |
| PATCH | /v3/domains/{domain_id}/config/{group}/{option} | keystone/api/domains.py:230 | identity:update_domain_config |
| GET | /v3/domains/config/{group}/{option}/default | keystone/api/domains.py:335 | identity:get_domain_config_default |
| GET | /v3/domains/config/{group}/default | keystone/api/domains.py:324 | identity:get_domain_config_default |
| GET | /v3/domains/config/default | keystone/api/domains.py:313 | identity:get_domain_config_default |
| GET | /v3/projects | keystone/api/projects.py:162 | identity:list_projects |
| POST | /v3/projects | keystone/api/projects.py:201 | identity:create_project |
| DELETE | /v3/projects/{project_id} | keystone/api/projects.py:138 | identity:delete_project |
| GET | /v3/projects/{project_id} | keystone/api/projects.py:105 | identity:get_project |
| PATCH | /v3/projects/{project_id} | keystone/api/projects.py:120 | identity:update_project |
| DELETE | /v3/projects/{project_id}/tags | keystone/api/projects.py:281 | identity:delete_project_tags |
| GET | /v3/projects/{project_id}/tags | keystone/api/projects.py:249 | identity:list_project_tags |
| PUT | /v3/projects/{project_id}/tags | keystone/api/projects.py:263 | identity:update_project_tags |
| DELETE | /v3/projects/{project_id}/tags/{value} | keystone/api/projects.py:335 | identity:delete_project_tag |
| GET | /v3/projects/{project_id}/tags/{value} | keystone/api/projects.py:297 | identity:get_project_tag |
| PUT | /v3/projects/{project_id}/tags/{value} | keystone/api/projects.py:311 | identity:create_project_tag |
Roles, implied roles and assignments (53 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| DELETE | /v3/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:169 | identity:revoke_grant |
| GET | /v3/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:123 | identity:check_grant |
| PUT | /v3/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:146 | identity:create_grant |
| GET | /v3/OS-INHERIT/domains/{domain_id}/groups/{group_id}/roles/inherited_to_projects | keystone/api/os_inherit.py:194 | identity:list_grants |
| DELETE | /v3/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:263 | identity:revoke_grant |
| GET | /v3/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:217 | identity:check_grant |
| PUT | /v3/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:240 | identity:create_grant |
| GET | /v3/OS-INHERIT/domains/{domain_id}/users/{user_id}/roles/inherited_to_projects | keystone/api/os_inherit.py:288 | identity:list_grants |
| DELETE | /v3/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:428 | identity:revoke_grant |
| GET | /v3/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:382 | identity:check_grant |
| PUT | /v3/OS-INHERIT/projects/{project_id}/groups/{group_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:405 | identity:create_grant |
| DELETE | /v3/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:357 | identity:revoke_grant |
| GET | /v3/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:311 | identity:check_grant |
| PUT | /v3/OS-INHERIT/projects/{project_id}/users/{user_id}/roles/{role_id}/inherited_to_projects | keystone/api/os_inherit.py:334 | identity:create_grant |
| GET | /v3/OS-TRUST/trusts/{trust_id}/roles | keystone/api/trusts.py:448 | identity:list_roles_for_trust |
| GET | /v3/OS-TRUST/trusts/{trust_id}/roles/{role_id} | keystone/api/trusts.py:503 | identity:get_role_for_trust |
| GET | /v3/domains/{domain_id}/groups/{group_id}/roles | keystone/api/domains.py:434 | identity:list_grants |
| DELETE | /v3/domains/{domain_id}/groups/{group_id}/roles/{role_id} | keystone/api/domains.py:496 | identity:revoke_grant |
| GET | /v3/domains/{domain_id}/groups/{group_id}/roles/{role_id} | keystone/api/domains.py:457 | identity:check_grant |
| PUT | /v3/domains/{domain_id}/groups/{group_id}/roles/{role_id} | keystone/api/domains.py:476 | identity:create_grant |
| GET | /v3/domains/{domain_id}/users/{user_id}/roles | keystone/api/domains.py:348 | identity:list_grants |
| DELETE | /v3/domains/{domain_id}/users/{user_id}/roles/{role_id} | keystone/api/domains.py:410 | identity:revoke_grant |
| GET | /v3/domains/{domain_id}/users/{user_id}/roles/{role_id} | keystone/api/domains.py:371 | identity:check_grant |
| PUT | /v3/domains/{domain_id}/users/{user_id}/roles/{role_id} | keystone/api/domains.py:390 | identity:create_grant |
| GET | /v3/projects/{project_id}/groups/{group_id}/roles | keystone/api/projects.py:579 | identity:list_grants |
| DELETE | /v3/projects/{project_id}/groups/{group_id}/roles/{role_id} | keystone/api/projects.py:550 | identity:revoke_grant |
| GET | /v3/projects/{project_id}/groups/{group_id}/roles/{role_id} | keystone/api/projects.py:499 | identity:check_grant |
| PUT | /v3/projects/{project_id}/groups/{group_id}/roles/{role_id} | keystone/api/projects.py:524 | identity:create_grant |
| GET | /v3/projects/{project_id}/users/{user_id}/roles | keystone/api/projects.py:474 | identity:list_grants |
| DELETE | /v3/projects/{project_id}/users/{user_id}/roles/{role_id} | keystone/api/projects.py:445 | identity:revoke_grant |
| GET | /v3/projects/{project_id}/users/{user_id}/roles/{role_id} | keystone/api/projects.py:394 | identity:check_grant |
| PUT | /v3/projects/{project_id}/users/{user_id}/roles/{role_id} | keystone/api/projects.py:419 | identity:create_grant |
| GET | /v3/role_assignments | keystone/api/role_assignments.py:39 | identity:list_role_assignments, identity:list_role_assignments_for_tree |
| GET | /v3/role_inferences | keystone/api/role_inferences.py:29 | identity:list_role_inference_rules |
| GET | /v3/roles | keystone/api/roles.py:44 | identity:list_domain_roles, identity:list_roles |
| POST | /v3/roles | keystone/api/roles.py:74 | identity:create_domain_role, identity:create_role |
| GET | /v3/roles/{prior_role_id}/implies | keystone/api/roles.py:221 | identity:list_implied_roles |
| DELETE | /v3/roles/{prior_role_id}/implies/{implied_role_id} | keystone/api/roles.py:311 | identity:delete_implied_role |
| GET | /v3/roles/{prior_role_id}/implies/{implied_role_id} | keystone/api/roles.py:268 | identity:get_implied_role |
| PUT | /v3/roles/{prior_role_id}/implies/{implied_role_id} | keystone/api/roles.py:296 | identity:create_implied_role |
| DELETE | /v3/roles/{role_id} | keystone/api/roles.py:176 | identity:delete_domain_role, identity:delete_role |
| GET | /v3/roles/{role_id} | keystone/api/roles.py:107 | identity:get_domain_role, identity:get_role |
| PATCH | /v3/roles/{role_id} | keystone/api/roles.py:142 | identity:update_domain_role, identity:update_role |
| GET | /v3/system/groups/{group_id}/roles | keystone/api/system.py:124 | identity:list_system_grants_for_group |
| DELETE | /v3/system/groups/{group_id}/roles/{role_id} | keystone/api/system.py:174 | identity:revoke_system_grant_for_group |
| GET | /v3/system/groups/{group_id}/roles/{role_id} | keystone/api/system.py:142 | identity:check_system_grant_for_group |
| PUT | /v3/system/groups/{group_id}/roles/{role_id} | keystone/api/system.py:158 | identity:create_system_grant_for_group |
| GET | /v3/system/users/{user_id}/roles | keystone/api/system.py:60 | identity:list_system_grants_for_user |
| DELETE | /v3/system/users/{user_id}/roles/{role_id} | keystone/api/system.py:106 | identity:revoke_system_grant_for_user |
| GET | /v3/system/users/{user_id}/roles/{role_id} | keystone/api/system.py:78 | identity:check_system_grant_for_user |
| PUT | /v3/system/users/{user_id}/roles/{role_id} | keystone/api/system.py:92 | identity:create_system_grant_for_user |
| GET | /v3/users/{user_id}/OS-OAUTH1/access_tokens/{access_token_id}/roles | keystone/api/users.py:625 | identity:list_access_token_roles |
| GET | /v3/users/{user_id}/OS-OAUTH1/access_tokens/{access_token_id}/roles/{role_id} | keystone/api/users.py:645 | identity:get_access_token_role |
Catalog: regions, services, endpoints (16 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/endpoints | keystone/api/endpoints.py:76 | identity:list_endpoints |
| POST | /v3/endpoints | keystone/api/endpoints.py:93 | identity:create_endpoint |
| DELETE | /v3/endpoints/{endpoint_id} | keystone/api/endpoints.py:143 | identity:delete_endpoint |
| GET | /v3/endpoints/{endpoint_id} | keystone/api/endpoints.py:115 | identity:get_endpoint |
| PATCH | /v3/endpoints/{endpoint_id} | keystone/api/endpoints.py:127 | identity:update_endpoint |
| GET | /v3/regions | keystone/api/regions.py:34 | identity:list_regions |
| POST | /v3/regions | keystone/api/regions.py:43 | identity:create_region |
| DELETE | /v3/regions/{region_id} | keystone/api/regions.py:104 | identity:delete_region |
| GET | /v3/regions/{region_id} | keystone/api/regions.py:64 | identity:get_region |
| PATCH | /v3/regions/{region_id} | keystone/api/regions.py:92 | identity:update_region |
| PUT | /v3/regions/{region_id} | keystone/api/regions.py:70 | identity:create_region |
| GET | /v3/services | keystone/api/services.py:32 | identity:list_services |
| POST | /v3/services | keystone/api/services.py:45 | identity:create_service |
| DELETE | /v3/services/{service_id} | keystone/api/services.py:90 | identity:delete_service |
| GET | /v3/services/{service_id} | keystone/api/services.py:65 | identity:get_service |
| PATCH | /v3/services/{service_id} | keystone/api/services.py:75 | identity:update_service |
Endpoint filtering and endpoint policies (35 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/OS-EP-FILTER/endpoint_groups | keystone/api/os_ep_filter.py:65 | identity:list_endpoint_groups |
| POST | /v3/OS-EP-FILTER/endpoint_groups | keystone/api/os_ep_filter.py:80 | identity:create_endpoint_group |
| DELETE | /v3/OS-EP-FILTER/endpoint_groups/{endpoint_group_id} | keystone/api/os_ep_filter.py:141 | identity:delete_endpoint_group |
| GET | /v3/OS-EP-FILTER/endpoint_groups/{endpoint_group_id} | keystone/api/os_ep_filter.py:111 | identity:get_endpoint_group |
| PATCH | /v3/OS-EP-FILTER/endpoint_groups/{endpoint_group_id} | keystone/api/os_ep_filter.py:123 | identity:update_endpoint_group |
| GET | /v3/OS-EP-FILTER/endpoint_groups/{endpoint_group_id}/endpoints | keystone/api/os_ep_filter.py:239 | identity:list_endpoints_associated_with_endpoint_group |
| GET | /v3/OS-EP-FILTER/endpoint_groups/{endpoint_group_id}/projects | keystone/api/os_ep_filter.py:216 | identity:list_projects_associated_with_endpoint_group |
| DELETE | /v3/OS-EP-FILTER/endpoint_groups/{endpoint_group_id}/projects/{project_id} | keystone/api/os_ep_filter.py:288 | identity:remove_endpoint_group_from_project |
| GET | /v3/OS-EP-FILTER/endpoint_groups/{endpoint_group_id}/projects/{project_id} | keystone/api/os_ep_filter.py:270 | identity:get_endpoint_group_in_project |
| PUT | /v3/OS-EP-FILTER/endpoint_groups/{endpoint_group_id}/projects/{project_id} | keystone/api/os_ep_filter.py:279 | identity:add_endpoint_group_to_project |
| GET | /v3/OS-EP-FILTER/endpoints/{endpoint_id}/projects | keystone/api/os_ep_filter.py:150 | identity:list_projects_for_endpoint |
| GET | /v3/OS-EP-FILTER/projects/{project_id}/endpoint_groups | keystone/api/os_ep_filter.py:206 | identity:list_endpoint_groups_for_project |
| GET | /v3/OS-EP-FILTER/projects/{project_id}/endpoints | keystone/api/os_ep_filter.py:192 | identity:list_endpoints_for_project |
| DELETE | /v3/OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id} | keystone/api/os_ep_filter.py:181 | identity:remove_endpoint_from_project |
| GET | /v3/OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id} | keystone/api/os_ep_filter.py:165 | identity:check_endpoint_in_project |
| PUT | /v3/OS-EP-FILTER/projects/{project_id}/endpoints/{endpoint_id} | keystone/api/os_ep_filter.py:174 | identity:add_endpoint_to_project |
| GET | /v3/endpoints/{endpoint_id}/OS-ENDPOINT-POLICY/policy | keystone/api/endpoints.py:152 | identity:get_policy_for_endpoint |
| DELETE | /v3/policies | keystone/api/policy.py:92 | identity:delete_policy |
| GET | /v3/policies | keystone/api/policy.py:38 | identity:list_policies |
| PATCH | /v3/policies | keystone/api/policy.py:78 | identity:update_policy |
| POST | /v3/policies | keystone/api/policy.py:63 | identity:create_policy |
| DELETE | /v3/policies/{policy_id} | keystone/api/policy.py:92 | identity:delete_policy |
| GET | /v3/policies/{policy_id} | keystone/api/policy.py:38 | identity:get_policy |
| PATCH | /v3/policies/{policy_id} | keystone/api/policy.py:78 | identity:update_policy |
| POST | /v3/policies/{policy_id} | keystone/api/policy.py:63 | identity:create_policy |
| GET | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/endpoints | keystone/api/policy.py:105 | identity:list_endpoints_for_policy |
| DELETE | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/endpoints/{endpoint_id} | keystone/api/policy.py:142 | identity:delete_policy_association_for_endpoint |
| GET | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/endpoints/{endpoint_id} | keystone/api/policy.py:122 | identity:check_policy_association_for_endpoint |
| PUT | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/endpoints/{endpoint_id} | keystone/api/policy.py:132 | identity:create_policy_association_for_endpoint |
| DELETE | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/services/{service_id} | keystone/api/policy.py:174 | identity:delete_policy_association_for_service |
| GET | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/services/{service_id} | keystone/api/policy.py:154 | identity:check_policy_association_for_service |
| PUT | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/services/{service_id} | keystone/api/policy.py:164 | identity:create_policy_association_for_service |
| DELETE | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/services/{service_id}/regions/{region_id} | keystone/api/policy.py:208 | identity:delete_policy_association_for_region_and_service |
| GET | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/services/{service_id}/regions/{region_id} | keystone/api/policy.py:186 | identity:check_policy_association_for_region_and_service |
| PUT | /v3/policies/{policy_id}/OS-ENDPOINT-POLICY/services/{service_id}/regions/{region_id} | keystone/api/policy.py:197 | identity:create_policy_association_for_region_and_service |
Trusts (4 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/OS-TRUST/trusts | keystone/api/trusts.py:223 | admin_required, identity:list_trusts, identity:list_trusts_for_trustee, identity:list_trusts_for_trustor |
| POST | /v3/OS-TRUST/trusts | keystone/api/trusts.py:296 | identity:create_trust |
| DELETE | /v3/OS-TRUST/trusts/{trust_id} | keystone/api/trusts.py:398 | identity:delete_trust |
| GET | /v3/OS-TRUST/trusts/{trust_id} | keystone/api/trusts.py:349 | identity:get_trust |
OAuth 1.0a and OAuth 2.0 (22 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/OS-OAUTH1/access_token | keystone/api/os_oauth1.py:96 | — |
| POST | /v3/OS-OAUTH1/access_token | keystone/api/os_oauth1.py:227 | none (unauthenticated) |
| GET | /v3/OS-OAUTH1/authorize/{request_token_id} | keystone/api/os_oauth1.py:96 | — |
| PUT | /v3/OS-OAUTH1/authorize/{request_token_id} | keystone/api/os_oauth1.py:327 | identity:authorize_request_token |
| DELETE | /v3/OS-OAUTH1/consumers | keystone/api/os_oauth1.py:137 | identity:delete_consumer |
| GET | /v3/OS-OAUTH1/consumers | keystone/api/os_oauth1.py:119 | identity:list_consumers |
| PATCH | /v3/OS-OAUTH1/consumers | keystone/api/os_oauth1.py:151 | identity:update_consumer |
| POST | /v3/OS-OAUTH1/consumers | keystone/api/os_oauth1.py:124 | identity:create_consumer |
| DELETE | /v3/OS-OAUTH1/consumers/{consumer_id} | keystone/api/os_oauth1.py:137 | identity:delete_consumer |
| GET | /v3/OS-OAUTH1/consumers/{consumer_id} | keystone/api/os_oauth1.py:119 | identity:get_consumer |
| PATCH | /v3/OS-OAUTH1/consumers/{consumer_id} | keystone/api/os_oauth1.py:151 | identity:update_consumer |
| POST | /v3/OS-OAUTH1/consumers/{consumer_id} | keystone/api/os_oauth1.py:124 | identity:create_consumer |
| GET | /v3/OS-OAUTH1/request_token | keystone/api/os_oauth1.py:96 | — |
| POST | /v3/OS-OAUTH1/request_token | keystone/api/os_oauth1.py:166 | none (unauthenticated) |
| DELETE | /v3/OS-OAUTH2/token | keystone/api/os_oauth2.py:68 | none (unauthenticated) |
| GET | /v3/OS-OAUTH2/token | keystone/api/os_oauth2.py:48 | none (unauthenticated) |
| PATCH | /v3/OS-OAUTH2/token | keystone/api/os_oauth2.py:63 | none (unauthenticated) |
| POST | /v3/OS-OAUTH2/token | keystone/api/os_oauth2.py:73 | none (unauthenticated) |
| PUT | /v3/OS-OAUTH2/token | keystone/api/os_oauth2.py:58 | none (unauthenticated) |
| GET | /v3/users/{user_id}/OS-OAUTH1/access_tokens | keystone/api/users.py:570 | identity:list_access_tokens |
| DELETE | /v3/users/{user_id}/OS-OAUTH1/access_tokens/{access_token_id} | keystone/api/users.py:596 | identity:delete_access_token |
| GET | /v3/users/{user_id}/OS-OAUTH1/access_tokens/{access_token_id} | keystone/api/users.py:583 | identity:get_access_token |
Unified limits (11 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/limits | keystone/api/limits.py:61 | identity:list_limits |
| POST | /v3/limits | keystone/api/limits.py:111 | identity:create_limits |
| DELETE | /v3/limits/{limit_id} | keystone/api/limits.py:169 | identity:delete_limit |
| GET | /v3/limits/{limit_id} | keystone/api/limits.py:140 | identity:get_limit |
| PATCH | /v3/limits/{limit_id} | keystone/api/limits.py:154 | identity:update_limit |
| GET | /v3/limits/model | keystone/api/limits.py:184 | identity:get_limit_model |
| GET | /v3/registered_limits | keystone/api/registered_limits.py:35 | identity:list_registered_limits |
| POST | /v3/registered_limits | keystone/api/registered_limits.py:54 | identity:create_registered_limits |
| DELETE | /v3/registered_limits/{registered_limit_id} | keystone/api/registered_limits.py:121 | identity:delete_registered_limit |
| GET | /v3/registered_limits/{registered_limit_id} | keystone/api/registered_limits.py:85 | identity:get_registered_limit |
| PATCH | /v3/registered_limits/{registered_limit_id} | keystone/api/registered_limits.py:100 | identity:update_registered_limit |
Revocation events and certificates (3 operations)
| Method | Path | Handler | Policy rule(s) |
|---|---|---|---|
| GET | /v3/OS-REVOKE/events | keystone/api/os_revoke.py:34 | identity:list_revoke_events |
| GET | /v3/OS-SIMPLE-CERT/ca | keystone/api/os_simple_cert.py:30 | none (unauthenticated) |
| GET | /v3/OS-SIMPLE-CERT/certificates | keystone/api/os_simple_cert.py:41 | none (unauthenticated) |
Source: reverse-spec-keystone/01-rest-api_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.