{"id":7483,"library":"oslo-policy","title":"Oslo Policy","description":"Oslo Policy is a core OpenStack library providing a robust and flexible authorization framework. It allows developers to define fine-grained access control rules using a policy file (JSON or YAML) and enforce them within their applications. As part of the OpenStack Oslo project, it is actively maintained with releases tied to the OpenStack development cycle, currently at version 5.0.0.","status":"active","version":"5.0.0","language":"en","source_language":"en","source_url":"https://github.com/openstack/oslo.policy","tags":["openstack","policy","authorization","rbac","security"],"install":[{"cmd":"pip install oslo-policy","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Commonly used for configuration management and policy file loading in OpenStack applications.","package":"oslo.config","optional":true}],"imports":[{"note":"While direct import works, `from oslo_policy import policy` then `policy.Enforcer` is the idiomatic way to access the main policy classes within the oslo-policy ecosystem.","wrong":"from oslo_policy.policy import Enforcer","symbol":"Enforcer","correct":"from oslo_policy import policy\nenforcer = policy.Enforcer(...)"},{"note":"Similar to Enforcer, accessing exceptions through the top-level 'policy' module is the standard pattern.","wrong":"from oslo_policy.policy import PolicyNotAuthorized","symbol":"PolicyNotAuthorized","correct":"from oslo_policy import policy\nexcept policy.PolicyNotAuthorized:"}],"quickstart":{"code":"from oslo_policy import policy\n\n# Define policy rules inline for simplicity.\n# In a real application, these would typically be loaded from a policy file\n# (e.g., policy.yaml or policy.json) configured via oslo.config.\n# Example: enforcer = policy.Enforcer(policy_file='path/to/policy.yaml')\nrules = {\n    \"admin_api\": \"role:admin\",\n    \"member_api\": \"role:member\",\n    \"owner_api\": \"project_id:%(project_id)s\"\n}\n\n# Initialize the Policy Enforcer\nenforcer = policy.Enforcer(rules=rules)\n\n# Context for an admin user\nadmin_context = {\n    \"user_id\": \"admin_user\",\n    \"roles\": [\"admin\"],\n    \"project_id\": \"admin_project\"\n}\n\n# Context for a regular member user\nmember_context = {\n    \"user_id\": \"member_user\",\n    \"roles\": [\"member\"],\n    \"project_id\": \"member_project\"\n}\n\n# Target data for owner check (e.g., a resource's project_id)\ntarget_data_owner = {\"project_id\": \"member_project\"}\ntarget_data_other = {\"project_id\": \"another_project\"}\n\n\nprint(\"--- Admin User Checks ---\")\ntry:\n    enforcer.authorize(\"admin_api\", admin_context)\n    print(\"Admin can access admin_api: YES\")\nexcept policy.PolicyNotAuthorized as e:\n    print(f\"Admin can access admin_api: NO ({e})\")\n\ntry:\n    enforcer.authorize(\"member_api\", admin_context)\n    print(\"Admin can access member_api: YES\")\nexcept policy.PolicyNotAuthorized as e:\n    print(f\"Admin can access member_api: NO ({e})\")\n\nprint(\"\\n--- Member User Checks ---\")\ntry:\n    enforcer.authorize(\"admin_api\", member_context)\n    print(\"Member can access admin_api: YES\")\nexcept policy.PolicyNotAuthorized as e:\n    print(f\"Member can access admin_api: NO ({e})\") # Expected: NO\n\ntry:\n    enforcer.authorize(\"member_api\", member_context)\n    print(\"Member can access member_api: YES\")\nexcept policy.PolicyNotAuthorized as e:\n    print(f\"Member can access member_api: NO ({e})\")\n\n# Check owner_api (member accessing their own project)\ntry:\n    enforcer.authorize(\"owner_api\", member_context, target_data_owner)\n    print(\"Member can access owner_api for their project: YES\")\nexcept policy.PolicyNotAuthorized as e:\n    print(f\"Member can access owner_api for their project: NO ({e})\")\n\n# Check owner_api (member accessing another project)\ntry:\n    enforcer.authorize(\"owner_api\", member_context, target_data_other)\n    print(\"Member can access owner_api for another project: YES\")\nexcept policy.PolicyNotAuthorized as e:\n    print(f\"Member can access owner_api for another project: NO ({e})\") # Expected: NO","lang":"python","description":"This quickstart demonstrates how to define policy rules, initialize an `Enforcer`, and use its `authorize` method to check permissions based on user context and target data. It shows successful and failed authorization attempts for different user roles and resource ownership scenarios."},"warnings":[{"fix":"Review all policy rules when upgrading. Explicitly define `rule:default` or `system_scope:authenticated` if you intend for authenticated users to have access, rather than relying on an empty string for the rule.","message":"The default policy rule has changed significantly in oslo-policy 5.0.0. Previously, a policy rule like `\"example_action\": \"\"` (empty string) implied `rule:default` (allowing any authenticated user). In 5.0.0+, the default for an unlisted rule is now `role:admin`.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Ensure the `policy_file` argument in `policy.Enforcer` points to a valid, accessible file. Use a tool like `yamllint` or `jsonlint` to validate the policy file syntax. Consider using absolute paths or robust path resolution for production systems.","message":"Incorrect or missing policy file paths can lead to `FileNotFoundError` or unexpected `PolicyNotAuthorized` exceptions if no rules are loaded. Policy files often use YAML or JSON formats, and syntax errors can be subtle.","severity":"gotcha","affected_versions":"All"},{"fix":"Always pass the user's details (roles, user ID, project ID) as the `context` dictionary. Pass the resource's attributes (e.g., its `project_id` for ownership checks) as the `target` dictionary. Rules often reference `%(project_id)s` from the target.","message":"Distinguishing between `context` and `target` parameters in `enforcer.authorize(rule, context, target)` can be confusing. `context` represents the current user/request attributes, while `target` represents the resource being accessed.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Inspect the policy rule that failed and the `context` and `target` dictionaries passed to `enforcer.authorize()`. Ensure the user's attributes (e.g., `roles`, `project_id`) match what the policy expects. Modify the policy rule or the user's context as needed.","cause":"The authorization context (user roles, project, etc.) does not satisfy the requirements defined by the policy rule.","error":"oslo_policy.policy.PolicyNotAuthorized: Policy doesn't allow [...] to perform [...] on [...]"},{"fix":"Verify that `policy.yaml` (or your policy file) exists at the path specified. Ensure the path is absolute or correctly relative to the script's execution directory. Double-check for typos in the filename or path.","cause":"The `policy_file` path provided to `policy.Enforcer` (or configured via `oslo.config`) is incorrect or the file does not exist at the specified location.","error":"FileNotFoundError: [Errno 2] No such file or directory: 'policy.yaml'"},{"fix":"Ensure all keys referenced in your policy rules (e.g., `user_id`, `project_id`, `is_admin`, `roles`) are present in the `context` or `target` dictionaries when calling `authorize()`. Provide default values for optional keys if appropriate.","cause":"A policy rule references a key (e.g., `%(project_id)s`) that is missing from either the `context` or `target` dictionary passed to `enforcer.authorize()` during evaluation.","error":"KeyError: 'project_id' (or similar key) during policy evaluation"}]}