Port RuleDefaults to DocumentedRuleDefaults

In preparation for implementaing basic default roles[1] within
Barbican moving RuleDefault to DocumentedRuleDefault in policy
files.

Route to policy work being updated and tracked in wiki[2].

[1] -
https://github.com/openstack/keystone-specs/blob/master/specs/keystone/rocky/define-default-roles.rst
[2] - https://wiki.openstack.org/wiki/Barbican/Policy

Co-Authored-By: Juan Antonio Osorio Robles <jaosorior@redhat.com>
Change-Id: I73dd0cf8a89dc24a44b6bc2151d95df632932ccc
This commit is contained in:
Harry Rybacki 2018-06-13 16:11:32 -04:00 committed by Juan Antonio Osorio Robles
parent 661386a517
commit 4d58ac8ddc
11 changed files with 685 additions and 173 deletions

View File

@ -12,25 +12,98 @@
from oslo_policy import policy
# FIXME(hrybacki): Repetitive check strings: Port to simpler checks
# - secret_acls:delete, secret_acls:put_patch
# - container_acls:delete container_acls:put_patch
rules = [
policy.RuleDefault('secret_acls:put_patch',
'rule:secret_project_admin or '
'rule:secret_project_creator'),
policy.RuleDefault('secret_acls:delete',
'rule:secret_project_admin or '
'rule:secret_project_creator'),
policy.RuleDefault('secret_acls:get',
'rule:all_but_audit and '
'rule:secret_project_match'),
policy.RuleDefault('container_acls:put_patch',
'rule:container_project_admin or '
'rule:container_project_creator'),
policy.RuleDefault('container_acls:delete',
'rule:container_project_admin or '
'rule:container_project_creator'),
policy.RuleDefault('container_acls:get',
'rule:all_but_audit and rule:container_project_match'),
policy.DocumentedRuleDefault(
name='secret_acls:get',
check_str='rule:all_but_audit and rule:secret_project_match',
scope_types=[],
description='Retrieve the ACL settings for a given secret.'
'If no ACL is defined for that secret, then Default ACL '
'is returned.',
operations=[
{
'path': '/v1/secrets/{secret-id}/acl',
'method': 'GET'
},
]
),
policy.DocumentedRuleDefault(
name='secret_acls:delete',
check_str='rule:secret_project_admin or rule:secret_project_creator',
scope_types=[],
description='Delete the ACL settings for a given secret.',
operations=[
{
'path': '/v1/secrets/{secret-id}/acl',
'method': 'DELETE'
},
]
),
policy.DocumentedRuleDefault(
name='secret_acls:put_patch',
check_str='rule:secret_project_admin or rule:secret_project_creator',
scope_types=[],
description='Create new, replaces, or updates existing ACL for a ' +
'given secret.',
operations=[
{
'path': '/v1/secrets/{secret-id}/acl',
'method': 'PUT'
},
{
'path': '/v1/secrets/{secret-id}/acl',
'method': 'PATCH'
},
]
),
policy.DocumentedRuleDefault(
name='container_acls:get',
check_str='rule:all_but_audit and rule:container_project_match',
scope_types=[],
description='Retrieve the ACL settings for a given container.',
operations=[
{
'path': '/v1/containers/{container-id}/acl',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='container_acls:delete',
check_str='rule:container_project_admin or ' +
'rule:container_project_creator',
scope_types=[],
description='Delete ACL for a given container. No content is returned '
'in the case of successful deletion.',
operations=[
{
'path': '/v1/containers/{container-id}/acl',
'method': 'DELETE'
}
]
),
policy.DocumentedRuleDefault(
name='container_acls:put_patch',
check_str='rule:container_project_admin or ' +
'rule:container_project_creator',
scope_types=[],
description='Create new or replaces existing ACL for a given '
'container.',
operations=[
{
'path': '/v1/containers/{container-id}/acl',
'method': 'PUT'
},
{
'path': '/v1/containers/{container-id}/acl',
'method': 'PATCH'
}
]
),
]

View File

@ -14,58 +14,81 @@ from oslo_policy import policy
rules = [
policy.RuleDefault('admin',
'role:admin'),
policy.RuleDefault('observer',
'role:observer'),
policy.RuleDefault('creator',
'role:creator'),
policy.RuleDefault('audit',
'role:audit'),
policy.RuleDefault('service_admin',
'role:key-manager:service-admin'),
policy.RuleDefault('admin_or_creator',
'rule:admin or rule:creator'),
policy.RuleDefault('all_but_audit',
'rule:admin or rule:observer or rule:creator'),
policy.RuleDefault('all_users',
'rule:admin or rule:observer or rule:creator or '
'rule:audit or rule:service_admin'),
policy.RuleDefault('secret_project_match',
'project:%(target.secret.project_id)s'),
policy.RuleDefault('secret_acl_read',
"'read':%(target.secret.read)s"),
policy.RuleDefault('secret_private_read',
"'False':%(target.secret.read_project_access)s"),
policy.RuleDefault('secret_creator_user',
"user:%(target.secret.creator_id)s"),
policy.RuleDefault('container_project_match',
"project:%(target.container.project_id)s"),
policy.RuleDefault('container_acl_read',
"'read':%(target.container.read)s"),
policy.RuleDefault('container_private_read',
"'False':%(target.container.read_project_access)s"),
policy.RuleDefault('container_creator_user',
"user:%(target.container.creator_id)s"),
policy.RuleDefault('secret_non_private_read',
"rule:all_users and rule:secret_project_match and "
"not rule:secret_private_read"),
policy.RuleDefault('secret_decrypt_non_private_read',
"rule:all_but_audit and rule:secret_project_match and "
"not rule:secret_private_read"),
policy.RuleDefault('container_non_private_read',
"rule:all_users and rule:container_project_match and "
"not rule:container_private_read"),
policy.RuleDefault('secret_project_admin',
"rule:admin and rule:secret_project_match"),
policy.RuleDefault('secret_project_creator',
"rule:creator and rule:secret_project_match and "
"rule:secret_creator_user"),
policy.RuleDefault('container_project_admin',
"rule:admin and rule:container_project_match"),
policy.RuleDefault('container_project_creator',
"rule:creator and rule:container_project_match and "
"rule:container_creator_user"),
policy.RuleDefault(
name='admin',
check_str='role:admin'),
policy.RuleDefault(
name='observer',
check_str='role:observer'),
policy.RuleDefault(
name='creator',
check_str='role:creator'),
policy.RuleDefault(
name='audit',
check_str='role:audit'),
policy.RuleDefault(
name='service_admin',
check_str='role:key-manager:service-admin'),
policy.RuleDefault(
name='admin_or_creator',
check_str='rule:admin or rule:creator'),
policy.RuleDefault(
name='all_but_audit',
check_str='rule:admin or rule:observer or rule:creator'),
policy.RuleDefault(
name='all_users',
check_str='rule:admin or rule:observer or rule:creator or ' +
'rule:audit or rule:service_admin'),
policy.RuleDefault(
name='secret_project_match',
check_str='project:%(target.secret.project_id)s'),
policy.RuleDefault(
name='secret_acl_read',
check_str="'read':%(target.secret.read)s"),
policy.RuleDefault(
name='secret_private_read',
check_str="'False':%(target.secret.read_project_access)s"),
policy.RuleDefault(
name='secret_creator_user',
check_str="user:%(target.secret.creator_id)s"),
policy.RuleDefault(
name='container_project_match',
check_str="project:%(target.container.project_id)s"),
policy.RuleDefault(
name='container_acl_read',
check_str="'read':%(target.container.read)s"),
policy.RuleDefault(
name='container_private_read',
check_str="'False':%(target.container.read_project_access)s"),
policy.RuleDefault(
name='container_creator_user',
check_str="user:%(target.container.creator_id)s"),
policy.RuleDefault(
name='secret_non_private_read',
check_str="rule:all_users and rule:secret_project_match and not " +
"rule:secret_private_read"),
policy.RuleDefault(
name='secret_decrypt_non_private_read',
check_str="rule:all_but_audit and rule:secret_project_match and not " +
"rule:secret_private_read"),
policy.RuleDefault(
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_admin',
check_str="rule:admin and rule:secret_project_match"),
policy.RuleDefault(
name='secret_project_creator',
check_str="rule:creator and rule:secret_project_match and " +
"rule:secret_creator_user"),
policy.RuleDefault(
name='container_project_admin',
check_str="rule:admin and rule:container_project_match"),
policy.RuleDefault(
name='container_project_creator',
check_str="rule:creator and rule:container_project_match and " +
"rule:container_creator_user"),
]

View File

@ -12,30 +12,71 @@
from oslo_policy import policy
# FIXME(hrybacki): Note that the GET rules have the same check strings.
# The POST/DELETE rules also share the check stirngs.
# These can probably be turned into constants in base
rules = [
policy.RuleDefault('consumer:get',
'rule:admin or rule:observer or rule:creator or '
'rule:audit or rule:container_non_private_read or '
'rule:container_project_creator or '
'rule:container_project_admin or '
'rule:container_acl_read'),
policy.RuleDefault('consumers:get',
'rule:admin or rule:observer or rule:creator or '
'rule:audit or rule:container_non_private_read or '
'rule:container_project_creator or '
'rule:container_project_admin or '
'rule:container_acl_read'),
policy.RuleDefault('consumers:post',
'rule:admin or rule:container_non_private_read or '
'rule:container_project_creator or '
'rule:container_project_admin or '
'rule:container_acl_read'),
policy.RuleDefault('consumers:delete',
'rule:admin or rule:container_non_private_read or '
'rule:container_project_creator or '
'rule:container_project_admin or '
'rule:container_acl_read'),
policy.DocumentedRuleDefault(
name='consumer:get',
check_str='rule:admin or rule:observer or rule:creator or ' +
'rule:audit or rule:container_non_private_read or ' +
'rule:container_project_creator or ' +
'rule:container_project_admin or rule:container_acl_read',
scope_types=[],
description='List a specific consumer for a given container.',
operations=[
{
'path': '/v1/containers/{container-id}/consumers/' +
'{consumer-id}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='consumers:get',
check_str='rule:admin or rule:observer or rule:creator or ' +
'rule:audit or rule:container_non_private_read or ' +
'rule:container_project_creator or ' +
'rule:container_project_admin or rule:container_acl_read',
scope_types=[],
description='List a containers consumers.',
operations=[
{
'path': '/v1/containers/{container-id}/consumers',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='consumers:post',
check_str='rule:admin or rule:container_non_private_read or ' +
'rule:container_project_creator or ' +
'rule:container_project_admin or rule:container_acl_read',
scope_types=[],
description='Creates a consumer.',
operations=[
{
'path': '/v1/containers/{container-id}/consumers',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name='consumers:delete',
check_str='rule:admin or rule:container_non_private_read or ' +
'rule:container_project_creator or ' +
'rule:container_project_admin or rule:container_acl_read',
scope_types=[],
description='Deletes a consumer.',
operations=[
{
'path': '/v1/containers/{container-id}/consumers/' +
'{consumer-id}',
'method': 'DELETE'
}
]
),
]

View File

@ -14,22 +14,82 @@ from oslo_policy import policy
rules = [
policy.RuleDefault('containers:post',
'rule:admin_or_creator'),
policy.RuleDefault('containers:get',
'rule:all_but_audit'),
policy.RuleDefault('container:get',
'rule:container_non_private_read or '
'rule:container_project_creator or '
'rule:container_project_admin or '
'rule:container_acl_read'),
policy.RuleDefault('container:delete',
'rule:container_project_admin or '
'rule:container_project_creator'),
policy.RuleDefault('container_secret:post',
'rule:admin'),
policy.RuleDefault('container_secret:delete',
'rule:admin'),
policy.DocumentedRuleDefault(
name='containers:post',
check_str='rule:admin_or_creator',
scope_types=[],
description='Creates a container.',
operations=[
{
'path': '/v1/containers',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name='containers:get',
check_str='rule:all_but_audit',
scope_types=[],
description='Lists a projects containers.',
operations=[
{
'path': '/v1/containers',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='container:get',
check_str='rule:container_non_private_read or ' +
'rule:container_project_creator or ' +
'rule:container_project_admin or ' +
'rule:container_acl_read',
scope_types=[],
description='Retrieves a single container.',
operations=[
{
'path': '/v1/containers/{container-id}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='container:delete',
check_str='rule:container_project_admin or ' +
'rule:container_project_creator',
scope_types=[],
description='Deletes a container.',
operations=[
{
'path': '/v1/containers/{uuid}',
'method': 'DELETE'
}
]
),
policy.DocumentedRuleDefault(
name='container_secret:post',
check_str='rule:admin',
scope_types=[],
description='Add a secret to an existing container.',
operations=[
{
'path': '/v1/containers/{container-id}/secrets',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name='container_secret:delete',
check_str='rule:admin',
scope_types=[],
description='Remove a secret from a container.',
operations=[
{
'path': '/v1/containers/{container-id}/secrets/{secret-id}',
'method': 'DELETE'
}
]
),
]

View File

@ -14,16 +14,66 @@ from oslo_policy import policy
rules = [
policy.RuleDefault('orders:post',
'rule:admin_or_creator'),
policy.RuleDefault('orders:get',
'rule:all_but_audit'),
policy.RuleDefault('orders:put',
'rule:admin_or_creator'),
policy.RuleDefault('order:get',
'rule:all_users'),
policy.RuleDefault('order:delete',
'rule:admin'),
policy.DocumentedRuleDefault(
name='orders:get',
check_str='rule:all_but_audit',
scope_types=[],
description='Gets list of all orders associated with a project.',
operations=[
{
'path': '/v1/orders',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='orders:post',
check_str='rule:admin_or_creator',
scope_types=[],
description='Creates an order.',
operations=[
{
'path': '/v1/orders',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name='orders:put',
check_str='rule:admin_or_creator',
scope_types=[],
description='Unsupported method for the orders API.',
operations=[
{
'path': '/v1/orders',
'method': 'PUT'
}
]
),
policy.DocumentedRuleDefault(
name='order:get',
check_str='rule:all_users',
scope_types=[],
description='Retrieves an orders metadata.',
operations=[
{
'path': '/v1/orders/{order-id}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='order:delete',
check_str='rule:admin',
scope_types=[],
description='Deletes an order.',
operations=[
{
'path': '/v1/orders/{order-id}',
'method': 'DELETE'
}
],
)
]

View File

@ -14,14 +14,60 @@ from oslo_policy import policy
rules = [
policy.RuleDefault('quotas:get',
'rule:all_users'),
policy.RuleDefault('project_quotas:get',
'rule:service_admin'),
policy.RuleDefault('project_quotas:put',
'rule:service_admin'),
policy.RuleDefault('project_quotas:delete',
'rule:service_admin'),
policy.DocumentedRuleDefault(
name='quotas:get',
check_str='rule:all_users',
scope_types=[],
description='List quotas for the project the user belongs to.',
operations=[
{
'path': '/v1/quotas',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='project_quotas:get',
check_str='rule:service_admin',
scope_types=[],
description='List quotas for the specified project.',
operations=[
{
'path': '/v1/project-quotas',
'method': 'GET'
},
{
'path': '/v1/project-quotas/{uuid}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='project_quotas:put',
check_str='rule:service_admin',
scope_types=[],
description='Create or update the configured project quotas for '
'the project with the specified UUID.',
operations=[
{
'path': '/v1/project-quotas/{uuid}',
'method': 'PUT'
}
]
),
policy.DocumentedRuleDefault(
name='project_quotas:delete',
check_str='rule:service_admin',
scope_types=[],
description='Delete the project quotas configuration for the '
'project with the requested UUID.',
operations=[
{
'path': '/v1/quotas}',
'method': 'DELETE'
}
]
),
]

View File

@ -14,14 +14,66 @@ from oslo_policy import policy
rules = [
policy.RuleDefault('secret_meta:get',
'rule:all_but_audit'),
policy.RuleDefault('secret_meta:post',
'rule:admin_or_creator'),
policy.RuleDefault('secret_meta:put',
'rule:admin_or_creator'),
policy.RuleDefault('secret_meta:delete',
'rule:admin_or_creator'),
policy.DocumentedRuleDefault(
name='secret_meta:get',
check_str='rule:all_but_audit',
scope_types=[],
description='metadata/: Lists a secrets user-defined metadata. || ' +
'metadata/{key}: Retrieves a secrets user-added metadata.',
operations=[
{
'path': '/v1/secrets/{secret-id}/metadata',
'method': 'GET'
},
{
'path': '/v1/secrets/{secret-id}/metadata/{meta-key}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='secret_meta:post',
check_str='rule:admin_or_creator',
scope_types=[],
description='Adds a new key/value pair to the secrets user-defined ' +
'metadata.',
operations=[
{
'path': '/v1/secrets/{secret-id}/metadata/{meta-key}',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name='secret_meta:put',
check_str='rule:admin_or_creator',
scope_types=[],
description='metadata/: Sets the user-defined metadata for a secret ' +
'|| metadata/{key}: Updates an existing key/value pair ' +
'in the secrets user-defined metadata.',
operations=[
{
'path': '/v1/secrets/{secret-id}/metadata',
'method': 'PUT'
},
{
'path': '/v1/secrets/{secret-id}/metadata/{meta-key}',
'method': 'PUT'
}
]
),
policy.DocumentedRuleDefault(
name='secret_meta:delete',
check_str='rule:admin_or_creator',
scope_types=[],
description='Delete secret user-defined metadata by key.',
operations=[
{
'path': '/v1/secrets/{secret-id}/metadata/{meta-key}',
'method': 'DELETE'
}
]
),
]

View File

@ -14,26 +14,83 @@ from oslo_policy import policy
rules = [
policy.RuleDefault('secret:decrypt',
'rule:secret_decrypt_non_private_read or '
'rule:secret_project_creator or '
'rule:secret_project_admin or '
'rule:secret_acl_read'),
policy.RuleDefault('secret:get',
'rule:secret_non_private_read or '
'rule:secret_project_creator or '
'rule:secret_project_admin or '
'rule:secret_acl_read'),
policy.RuleDefault('secret:put',
'rule:admin_or_creator and '
'rule:secret_project_match'),
policy.RuleDefault('secret:delete',
'rule:secret_project_admin or '
'rule:secret_project_creator'),
policy.RuleDefault('secrets:post',
'rule:admin_or_creator'),
policy.RuleDefault('secrets:get',
'rule:all_but_audit'),
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',
scope_types=[],
description='Retrieve a secrets payload.',
operations=[
{
'path': '/v1/secrets/{uuid}/payload',
'method': 'GET'
}
]
),
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',
scope_types=[],
description='Retrieves a secrets metadata.',
operations=[
{
'path': '/v1/secrets/{secret-id}',
'method': 'GET"'
}
]
),
policy.DocumentedRuleDefault(
name='secret:put',
check_str='rule:admin_or_creator and rule:secret_project_match',
scope_types=[],
description='Add the payload to an existing metadata-only secret.',
operations=[
{
'path': '/v1/secrets/{secret-id}',
'method': 'PUT'
}
]
),
policy.DocumentedRuleDefault(
name='secret:delete',
check_str='rule:secret_project_admin or ' +
'rule:secret_project_creator',
scope_types=[],
description='Delete a secret by uuid.',
operations=[
{
'path': '/v1/secrets/{secret-id}',
'method': 'DELETE'
}
]
),
policy.DocumentedRuleDefault(
name='secrets:post',
check_str='rule:admin_or_creator',
scope_types=[],
description='Creates a Secret entity.',
operations=[
{
'path': '/v1/secrets',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name='secrets:get',
check_str='rule:all_but_audit',
scope_types=[],
description='Lists a projects secrets.',
operations=[
{
'path': '/v1/secrets',
'method': 'GET'
}
]
)
]

View File

@ -14,18 +14,82 @@ from oslo_policy import policy
rules = [
policy.RuleDefault('secretstores:get',
'rule:admin'),
policy.RuleDefault('secretstores:get_global_default',
'rule:admin'),
policy.RuleDefault('secretstores:get_preferred',
'rule:admin'),
policy.RuleDefault('secretstore_preferred:post',
'rule:admin'),
policy.RuleDefault('secretstore_preferred:delete',
'rule:admin'),
policy.RuleDefault('secretstore:get',
'rule:admin'),
policy.DocumentedRuleDefault(
name='secretstores:get',
check_str='rule:admin',
scope_types=[],
description='Get list of available secret store backends.',
operations=[
{
'path': '/v1/secret-stores',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='secretstores:get_global_default',
check_str='rule:admin',
scope_types=[],
description='Get a reference to the secret store that is used as ' +
'default secret store backend for the deployment.',
operations=[
{
'path': '/v1/secret-stores/global-default',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='secretstores:get_preferred',
check_str='rule:admin',
scope_types=[],
description='Get a reference to the preferred secret store if ' +
'assigned previously.',
operations=[
{
'path': '/v1/secret-stores/preferred',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='secretstore_preferred:post',
check_str='rule:admin',
scope_types=[],
description='Set a secret store backend to be preferred store ' +
'backend for their project.',
operations=[
{
'path': '/v1/secret-stores/{ss-id}/preferred',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name='secretstore_preferred:delete',
check_str='rule:admin',
scope_types=[],
description='Remove preferred secret store backend setting for ' +
'their project.',
operations=[
{
'path': '/v1/secret-stores/{ss-id}/preferred',
'method': 'DELETE'
}
]
),
policy.DocumentedRuleDefault(
name='secretstore:get',
check_str='rule:admin',
scope_types=[],
description='Get details of secret store by its ID.',
operations=[
{
'path': '/v1/secret-stores/{ss-id}',
'method': 'GET'
}
]
),
]

View File

@ -14,14 +14,55 @@ from oslo_policy import policy
rules = [
policy.RuleDefault('transport_key:get',
'rule:all_users'),
policy.RuleDefault('transport_key:delete',
'rule:admin'),
policy.RuleDefault('transport_keys:get',
'rule:all_users'),
policy.RuleDefault('transport_keys:post',
'rule:admin'),
policy.DocumentedRuleDefault(
name='transport_key:get',
check_str='rule:all_users',
scope_types=[],
description='Get a specific transport key.',
operations=[
{
'path': '/v1/transport_keys/{key-id}}',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='transport_key:delete',
check_str='rule:admin',
scope_types=[],
description='Delete a specific transport key.',
operations=[
{
'path': '/v1/transport_keys/{key-id}',
'method': 'DELETE'
}
]
),
policy.DocumentedRuleDefault(
name='transport_keys:get',
check_str='rule:all_users',
scope_types=[],
description='Get a list of all transport keys.',
operations=[
{
'path': '/v1/transport_keys',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name='transport_keys:post',
check_str='rule:admin',
scope_types=[],
description='Create a new transport key.',
operations=[
{
'path': '/v1/transport_keys',
'method': 'POST'
}
]
),
]

View File

@ -0,0 +1,5 @@
---
features:
- |
Port existing policy RuleDefault objects to the newer, more verbose
DocumentedRuleDefaults.