Merge "Fix Secure RBAC policies for Secrets"
This commit is contained in:
commit
198aee70a4
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 " +
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user