Merge "Fix Secure RBAC policies for Secrets"

This commit is contained in:
Zuul 2022-08-24 21:51:06 +00:00 committed by Gerrit Code Review
commit 198aee70a4
3 changed files with 106 additions and 37 deletions

View File

@ -18,9 +18,12 @@ from webob import exc
from barbican import api from barbican import api
from barbican.common import accept from barbican.common import accept
from barbican.common import config
from barbican.common import utils from barbican.common import utils
from barbican import i18n as u from barbican import i18n as u
CONF = config.CONF
LOG = utils.getLogger(__name__) 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 action_name = 'secret:decrypt' # Override to perform special rules
target_name, target_data = inst.get_acl_tuple(req, **kwargs) 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: if target_name and target_data:
policy_dict['target'] = {target_name: target_data} policy_dict['target'] = {target_name: target_data}
policy_dict.update(kwargs) policy_dict.update(kwargs)
# Enforce access controls. # Enforce access controls.
if ctx.policy_enforcer: 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) ctx, do_raise=True)

View File

@ -75,9 +75,21 @@ rules = [
name='container_non_private_read', name='container_non_private_read',
check_str="rule:all_users and rule:container_project_match and not " + check_str="rule:all_users and rule:container_project_match and not " +
"rule:container_private_read"), "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( policy.RuleDefault(
name='secret_project_admin', 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( policy.RuleDefault(
name='secret_project_creator', name='secret_project_creator',
check_str="rule:creator and rule:secret_project_match and " + check_str="rule:creator and rule:secret_project_match and " +

View File

@ -10,25 +10,68 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from oslo_log import versionutils
from oslo_policy import policy from oslo_policy import policy
_READER = "role:reader" _LEGACY_POLICY_DEPRECATION = (
_MEMBER = "role:member" 'The default policy for the Key Manager API has been updated '
_ADMIN = "role:admin" 'to use scopes and default roles.'
_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" deprecated_secret_decrypt = policy.DeprecatedRule(
_SECRET_IS_NOT_PRIVATE = "True:%(target.secret.read_project_access)s" 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 = [ rules = [
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name='secret:decrypt', name='secret:decrypt',
check_str='rule:secret_decrypt_non_private_read or ' + check_str=(
'rule:secret_project_creator or ' + "True:%(enforce_new_defaults)s and "
'rule:secret_project_admin or rule:secret_acl_read or ' + "(rule:secret_project_admin or "
f"({_PROJECT_MEMBER} and ({_SECRET_CREATOR} or " + "(rule:secret_project_member and rule:secret_owner) or "
f"{_SECRET_IS_NOT_PRIVATE})) or {_PROJECT_ADMIN}", "(rule:secret_project_member and rule:secret_is_not_private) or "
"rule:secret_acl_read)"),
scope_types=['project'], scope_types=['project'],
description='Retrieve a secrets payload.', description='Retrieve a secrets payload.',
operations=[ operations=[
@ -36,15 +79,17 @@ rules = [
'path': '/v1/secrets/{uuid}/payload', 'path': '/v1/secrets/{uuid}/payload',
'method': 'GET' 'method': 'GET'
} }
] ],
deprecated_rule=deprecated_secret_decrypt
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name='secret:get', name='secret:get',
check_str='rule:secret_non_private_read or ' + check_str=(
'rule:secret_project_creator or ' + "True:%(enforce_new_defaults)s and "
'rule:secret_project_admin or rule:secret_acl_read or ' + "(rule:secret_project_admin or "
f"({_PROJECT_MEMBER} and ({_SECRET_CREATOR} or " + "(rule:secret_project_member and rule:secret_owner) or "
f"{_SECRET_IS_NOT_PRIVATE})) or {_PROJECT_ADMIN}", "(rule:secret_project_member and rule:secret_is_not_private) or "
"rule:secret_acl_read)"),
scope_types=['project'], scope_types=['project'],
description='Retrieves a secrets metadata.', description='Retrieves a secrets metadata.',
operations=[ operations=[
@ -52,13 +97,16 @@ rules = [
'path': '/v1/secrets/{secret-id}', 'path': '/v1/secrets/{secret-id}',
'method': 'GET' 'method': 'GET'
} }
] ],
deprecated_rule=deprecated_secret_get
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name='secret:put', name='secret:put',
check_str='rule:admin_or_creator and rule:secret_project_match or ' + check_str=(
f"({_PROJECT_MEMBER} and ({_SECRET_CREATOR} or " + "True:%(enforce_new_defaults)s and "
f"{_SECRET_IS_NOT_PRIVATE})) or {_PROJECT_ADMIN}", "(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'], scope_types=['project'],
description='Add the payload to an existing metadata-only secret.', description='Add the payload to an existing metadata-only secret.',
operations=[ operations=[
@ -66,16 +114,16 @@ rules = [
'path': '/v1/secrets/{secret-id}', 'path': '/v1/secrets/{secret-id}',
'method': 'PUT' 'method': 'PUT'
} }
] ],
deprecated_rule=deprecated_secret_put
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name='secret:delete', name='secret:delete',
check_str='rule:secret_project_admin or ' + check_str=(
'rule:secret_project_creator or ' + "True:%(enforce_new_defaults)s and "
'(rule:secret_project_creator_role and ' + "(rule:secret_project_admin or "
'not rule:secret_private_read) or ' + "(rule:secret_project_member and rule:secret_owner) or "
f"({_PROJECT_MEMBER} and ({_SECRET_CREATOR} or " + "(rule:secret_project_member and rule:secret_is_not_private))"),
f"{_SECRET_IS_NOT_PRIVATE})) or {_PROJECT_ADMIN}",
scope_types=['project'], scope_types=['project'],
description='Delete a secret by uuid.', description='Delete a secret by uuid.',
operations=[ operations=[
@ -83,11 +131,12 @@ rules = [
'path': '/v1/secrets/{secret-id}', 'path': '/v1/secrets/{secret-id}',
'method': 'DELETE' 'method': 'DELETE'
} }
] ],
deprecated_rule=deprecated_secret_delete
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name='secrets:post', 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'], scope_types=['project'],
description='Creates a Secret entity.', description='Creates a Secret entity.',
operations=[ operations=[
@ -95,11 +144,12 @@ rules = [
'path': '/v1/secrets', 'path': '/v1/secrets',
'method': 'POST' 'method': 'POST'
} }
] ],
deprecated_rule=deprecated_secrets_post
), ),
policy.DocumentedRuleDefault( policy.DocumentedRuleDefault(
name='secrets:get', 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'], scope_types=['project'],
description='Lists a projects secrets.', description='Lists a projects secrets.',
operations=[ operations=[
@ -107,7 +157,8 @@ rules = [
'path': '/v1/secrets', 'path': '/v1/secrets',
'method': 'GET' 'method': 'GET'
} }
] ],
deprecated_rule=deprecated_secrets_get
) )
] ]