diff --git a/barbican/api/controllers/__init__.py b/barbican/api/controllers/__init__.py index 8c9d0a5d2..e5db8cbf4 100644 --- a/barbican/api/controllers/__init__.py +++ b/barbican/api/controllers/__init__.py @@ -18,9 +18,12 @@ from webob import exc from barbican import api from barbican.common import accept +from barbican.common import config from barbican.common import utils from barbican import i18n as u + +CONF = config.CONF LOG = utils.getLogger(__name__) @@ -55,14 +58,17 @@ def _do_enforce_rbac(inst, req, action_name, ctx, **kwargs): action_name = 'secret:decrypt' # Override to perform special rules target_name, target_data = inst.get_acl_tuple(req, **kwargs) - policy_dict = {} + policy_dict = { + "enforce_new_defaults": CONF.oslo_policy.enforce_new_defaults + } if target_name and target_data: policy_dict['target'] = {target_name: target_data} policy_dict.update(kwargs) # Enforce access controls. if ctx.policy_enforcer: - ctx.policy_enforcer.authorize(action_name, flatten(policy_dict), + target = flatten(policy_dict) + ctx.policy_enforcer.authorize(action_name, target, ctx, do_raise=True) diff --git a/barbican/common/policies/base.py b/barbican/common/policies/base.py index 6b4cb1f3d..fddd53360 100644 --- a/barbican/common/policies/base.py +++ b/barbican/common/policies/base.py @@ -75,9 +75,21 @@ rules = [ name='container_non_private_read', check_str="rule:all_users and rule:container_project_match and not " + "rule:container_private_read"), + policy.RuleDefault( + name='secret_project_reader', + check_str='role:reader and rule:secret_project_match'), + policy.RuleDefault( + name='secret_project_member', + check_str='role:member and rule:secret_project_match'), policy.RuleDefault( name='secret_project_admin', - check_str="rule:admin and rule:secret_project_match"), + check_str='rule:admin and rule:secret_project_match'), + policy.RuleDefault( + name='secret_owner', + check_str='user_id:%(target.secret.creator_id)s'), + policy.RuleDefault( + name='secret_is_not_private', + check_str='True:%(target.secret.read_project_access)s'), policy.RuleDefault( name='secret_project_creator', check_str="rule:creator and rule:secret_project_match and " + diff --git a/barbican/common/policies/secrets.py b/barbican/common/policies/secrets.py index 1070c0b69..bed56a48e 100644 --- a/barbican/common/policies/secrets.py +++ b/barbican/common/policies/secrets.py @@ -10,25 +10,68 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_log import versionutils from oslo_policy import policy -_READER = "role:reader" -_MEMBER = "role:member" -_ADMIN = "role:admin" -_PROJECT_MEMBER = f"{_MEMBER} and project_id:%(target.secret.project_id)s" -_PROJECT_ADMIN = f"{_ADMIN} and project_id:%(target.secret.project_id)s" -_SECRET_CREATOR = "user_id:%(target.secret.creator_id)s" -_SECRET_IS_NOT_PRIVATE = "True:%(target.secret.read_project_access)s" +_LEGACY_POLICY_DEPRECATION = ( + 'The default policy for the Key Manager API has been updated ' + 'to use scopes and default roles.' +) + +deprecated_secret_decrypt = policy.DeprecatedRule( + name='secret:decrypt', + check_str='rule:secret_decrypt_non_private_read or ' + + 'rule:secret_project_creator or ' + + 'rule:secret_project_admin or rule:secret_acl_read', + deprecated_reason=_LEGACY_POLICY_DEPRECATION, + deprecated_since=versionutils.deprecated.ZED +) +deprecated_secret_get = policy.DeprecatedRule( + name='secret:get', + check_str='rule:secret_non_private_read or ' + + 'rule:secret_project_creator or ' + + 'rule:secret_project_admin or rule:secret_acl_read', + deprecated_reason=_LEGACY_POLICY_DEPRECATION, + deprecated_since=versionutils.deprecated.ZED +) +deprecated_secret_put = policy.DeprecatedRule( + name='secret:put', + check_str='rule:admin_or_creator and rule:secret_project_match', + deprecated_reason=_LEGACY_POLICY_DEPRECATION, + deprecated_since=versionutils.deprecated.ZED +) +deprecated_secret_delete = policy.DeprecatedRule( + name='secret:delete', + check_str='rule:secret_project_admin or ' + + 'rule:secret_project_creator or ' + + '(rule:secret_project_creator_role and ' + + 'not rule:secret_private_read)', + deprecated_reason=_LEGACY_POLICY_DEPRECATION, + deprecated_since=versionutils.deprecated.ZED +) +deprecated_secrets_post = policy.DeprecatedRule( + name='secrets:post', + check_str='rule:admin_or_creator', + deprecated_reason=_LEGACY_POLICY_DEPRECATION, + deprecated_since=versionutils.deprecated.ZED +) +deprecated_secrets_get = policy.DeprecatedRule( + name='secrets:get', + check_str='rule:all_but_audit', + deprecated_reason=_LEGACY_POLICY_DEPRECATION, + deprecated_since=versionutils.deprecated.ZED +) rules = [ policy.DocumentedRuleDefault( name='secret:decrypt', - check_str='rule:secret_decrypt_non_private_read or ' + - 'rule:secret_project_creator or ' + - 'rule:secret_project_admin or rule:secret_acl_read or ' + - f"({_PROJECT_MEMBER} and ({_SECRET_CREATOR} or " + - f"{_SECRET_IS_NOT_PRIVATE})) or {_PROJECT_ADMIN}", + check_str=( + "True:%(enforce_new_defaults)s and " + "(rule:secret_project_admin or " + "(rule:secret_project_member and rule:secret_owner) or " + "(rule:secret_project_member and rule:secret_is_not_private) or " + "rule:secret_acl_read)"), scope_types=['project'], description='Retrieve a secrets payload.', operations=[ @@ -36,15 +79,17 @@ rules = [ 'path': '/v1/secrets/{uuid}/payload', 'method': 'GET' } - ] + ], + deprecated_rule=deprecated_secret_decrypt ), policy.DocumentedRuleDefault( name='secret:get', - check_str='rule:secret_non_private_read or ' + - 'rule:secret_project_creator or ' + - 'rule:secret_project_admin or rule:secret_acl_read or ' + - f"({_PROJECT_MEMBER} and ({_SECRET_CREATOR} or " + - f"{_SECRET_IS_NOT_PRIVATE})) or {_PROJECT_ADMIN}", + check_str=( + "True:%(enforce_new_defaults)s and " + "(rule:secret_project_admin or " + "(rule:secret_project_member and rule:secret_owner) or " + "(rule:secret_project_member and rule:secret_is_not_private) or " + "rule:secret_acl_read)"), scope_types=['project'], description='Retrieves a secrets metadata.', operations=[ @@ -52,13 +97,16 @@ rules = [ 'path': '/v1/secrets/{secret-id}', 'method': 'GET' } - ] + ], + deprecated_rule=deprecated_secret_get ), policy.DocumentedRuleDefault( name='secret:put', - check_str='rule:admin_or_creator and rule:secret_project_match or ' + - f"({_PROJECT_MEMBER} and ({_SECRET_CREATOR} or " + - f"{_SECRET_IS_NOT_PRIVATE})) or {_PROJECT_ADMIN}", + check_str=( + "True:%(enforce_new_defaults)s and " + "(rule:secret_project_admin or " + "(rule:secret_project_member and rule:secret_owner) or " + "(rule:secret_project_member and rule:secret_is_not_private))"), scope_types=['project'], description='Add the payload to an existing metadata-only secret.', operations=[ @@ -66,16 +114,16 @@ rules = [ 'path': '/v1/secrets/{secret-id}', 'method': 'PUT' } - ] + ], + deprecated_rule=deprecated_secret_put ), policy.DocumentedRuleDefault( name='secret:delete', - check_str='rule:secret_project_admin or ' + - 'rule:secret_project_creator or ' + - '(rule:secret_project_creator_role and ' + - 'not rule:secret_private_read) or ' + - f"({_PROJECT_MEMBER} and ({_SECRET_CREATOR} or " + - f"{_SECRET_IS_NOT_PRIVATE})) or {_PROJECT_ADMIN}", + check_str=( + "True:%(enforce_new_defaults)s and " + "(rule:secret_project_admin or " + "(rule:secret_project_member and rule:secret_owner) or " + "(rule:secret_project_member and rule:secret_is_not_private))"), scope_types=['project'], description='Delete a secret by uuid.', operations=[ @@ -83,11 +131,12 @@ rules = [ 'path': '/v1/secrets/{secret-id}', 'method': 'DELETE' } - ] + ], + deprecated_rule=deprecated_secret_delete ), policy.DocumentedRuleDefault( name='secrets:post', - check_str=f'rule:admin_or_creator or {_MEMBER}', + check_str=f'True:%(enforce_new_defaults)s and role:member', scope_types=['project'], description='Creates a Secret entity.', operations=[ @@ -95,11 +144,12 @@ rules = [ 'path': '/v1/secrets', 'method': 'POST' } - ] + ], + deprecated_rule=deprecated_secrets_post ), policy.DocumentedRuleDefault( name='secrets:get', - check_str=f'rule:all_but_audit or {_MEMBER}', + check_str=f'True:%(enforce_new_defaults)s and role:member', scope_types=['project'], description='Lists a projects secrets.', operations=[ @@ -107,7 +157,8 @@ rules = [ 'path': '/v1/secrets', 'method': 'GET' } - ] + ], + deprecated_rule=deprecated_secrets_get ) ]