DECKHAND-61: oslo.policy integration
This PS implements oslo.policy integration in Deckhand.
The policy.py file implements 2 types of functions for
performing policy enforcement in Deckhand: authorize,
which is a decorator that is used directly around
falcon on_HTTP_VERB methods that raises a 403 immediately
if policy enforcement fails; and conditional_authorize,
to be used inside controller code conditionally.
For example, since Deckhand has two types of documents
with respect to security -- encrypted and cleartext
documents -- policy enforcement is conditioned on the
type of the documents' metadata.storagePolicy.
Included in this PS:
- policy framework implementation
- policy in code and policy documentation for all
Deckhand policies
- modification of functional test script to override
default admin-only policies with custom policy file
dynamically created using lax permissions
- bug fix for filtering out deleted documents (and
its predecessors in previous revisions) for
PUT /revisions/{revision_id}/documents
- policy documentation
- basic unit tests for policy enforcement framework
- allow functional tests to be filtered via regex
Due to the size of this PS, functional tests related to
policy enforcement will be done in a follow up.
Change-Id: If418129f9b401091e098c0bd6c7336b8a5cd2359
This commit is contained in:
29
deckhand/policies/__init__.py
Normal file
29
deckhand/policies/__init__.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import itertools
|
||||
|
||||
from deckhand.policies import base
|
||||
from deckhand.policies import document
|
||||
from deckhand.policies import revision
|
||||
from deckhand.policies import revision_tag
|
||||
|
||||
|
||||
def list_rules():
|
||||
return itertools.chain(
|
||||
base.list_rules(),
|
||||
document.list_rules(),
|
||||
revision.list_rules(),
|
||||
revision_tag.list_rules()
|
||||
)
|
||||
30
deckhand/policies/base.py
Normal file
30
deckhand/policies/base.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo_policy import policy
|
||||
|
||||
POLICY_ROOT = 'deckhand:%s'
|
||||
RULE_ADMIN_API = 'rule:admin_api'
|
||||
|
||||
|
||||
rules = [
|
||||
policy.RuleDefault(
|
||||
"admin_api",
|
||||
"role:admin",
|
||||
"Default rule for most Admin APIs.")
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return rules
|
||||
105
deckhand/policies/document.py
Normal file
105
deckhand/policies/document.py
Normal file
@@ -0,0 +1,105 @@
|
||||
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo_policy import policy
|
||||
|
||||
from deckhand.policies import base
|
||||
|
||||
|
||||
document_policies = [
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'create_cleartext_documents',
|
||||
base.RULE_ADMIN_API,
|
||||
"""Create a batch of documents specified in the request body, whereby
|
||||
a new revision is created. Also, roll back a revision to a previous one in the
|
||||
revision history, whereby the target revision's documents are re-created for
|
||||
the new revision.
|
||||
|
||||
Conditionally enforced for the endpoints below if the any of the documents in
|
||||
the request body have a `metadata.storagePolicy` of "cleartext".""",
|
||||
[
|
||||
{
|
||||
'method': 'PUT',
|
||||
'path': '/api/v1.0/bucket/{bucket_name}/documents'
|
||||
},
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/api/v1.0/rollback/{target_revision_id}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'create_encrypted_documents',
|
||||
base.RULE_ADMIN_API,
|
||||
"""Create a batch of documents specified in the request body, whereby
|
||||
a new revision is created. Also, roll back a revision to a previous one in the
|
||||
history, whereby the target revision's documents are re-created for the new
|
||||
revision.
|
||||
|
||||
Conditionally enforced for the endpoints below if the any of the documents in
|
||||
the request body have a `metadata.storagePolicy` of "encrypted".""",
|
||||
[
|
||||
{
|
||||
'method': 'PUT',
|
||||
'path': '/api/v1.0/bucket/{bucket_name}/documents'
|
||||
},
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/api/v1.0/rollback/{target_revision_id}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'list_cleartext_documents',
|
||||
base.RULE_ADMIN_API,
|
||||
"""List cleartext documents for a revision (with no layering or
|
||||
substitution applied) as well as fully layered and substituted concrete
|
||||
documents.
|
||||
|
||||
Conditionally enforced for the endpoints below if the any of the documents in
|
||||
the request body have a `metadata.storagePolicy` of "cleartext". If policy
|
||||
enforcement fails, cleartext documents are omitted.""",
|
||||
[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': 'api/v1.0/revisions/{revision_id}/documents'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': 'api/v1.0/revisions/{revision_id}/rendered-documents'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'list_encrypted_documents',
|
||||
base.RULE_ADMIN_API,
|
||||
"""List cleartext documents for a revision (with no layering or
|
||||
substitution applied) as well as fully layered and substituted concrete
|
||||
documents.
|
||||
|
||||
Conditionally enforced for the endpoints below if the any of the documents in
|
||||
the request body have a `metadata.storagePolicy` of "encrypted". If policy
|
||||
enforcement fails, encrypted documents are omitted.""",
|
||||
[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': 'api/v1.0/revisions/{revision_id}/documents'
|
||||
},
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': 'api/v1.0/revisions/{revision_id}/rendered-documents'
|
||||
}
|
||||
]),
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return document_policies
|
||||
66
deckhand/policies/revision.py
Normal file
66
deckhand/policies/revision.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo_policy import policy
|
||||
|
||||
from deckhand.policies import base
|
||||
|
||||
|
||||
revision_policies = [
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'show_revision',
|
||||
base.RULE_ADMIN_API,
|
||||
"Show details for a revision tag.",
|
||||
[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/api/v1.0/revisions/{revision_id}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'list_revisions',
|
||||
base.RULE_ADMIN_API,
|
||||
"List all revisions.",
|
||||
[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/api/v1.0/revisions'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'delete_revisions',
|
||||
base.RULE_ADMIN_API,
|
||||
"Delete all revisions.",
|
||||
[
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/api/v1.0/revisions'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'show_revision_diff',
|
||||
base.RULE_ADMIN_API,
|
||||
"Show revision diff between two revisions.",
|
||||
[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': ('/api/v1.0/revisions/{revision_id}/diff/'
|
||||
'{comparison_revision_id}')
|
||||
}
|
||||
]),
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return revision_policies
|
||||
75
deckhand/policies/revision_tag.py
Normal file
75
deckhand/policies/revision_tag.py
Normal file
@@ -0,0 +1,75 @@
|
||||
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from oslo_policy import policy
|
||||
|
||||
from deckhand.policies import base
|
||||
|
||||
|
||||
revision_tag_policies = [
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'create_tag',
|
||||
base.RULE_ADMIN_API,
|
||||
"Create a revision tag.",
|
||||
[
|
||||
{
|
||||
'method': 'POST',
|
||||
'path': '/api/v1.0/revisions/{revision_id}/tags'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'show_tag',
|
||||
base.RULE_ADMIN_API,
|
||||
"Show details for a revision tag.",
|
||||
[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/api/v1.0/revisions/{revision_id}/tags/{tag}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'list_tags',
|
||||
base.RULE_ADMIN_API,
|
||||
"List all tags for a revision.",
|
||||
[
|
||||
{
|
||||
'method': 'GET',
|
||||
'path': '/api/v1.0/revisions/{revision_id}/tags'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'delete_tag',
|
||||
base.RULE_ADMIN_API,
|
||||
"Delete a revision tag.",
|
||||
[
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/api/v1.0/revisions/{revision_id}/tags/{tag}'
|
||||
}
|
||||
]),
|
||||
policy.DocumentedRuleDefault(
|
||||
base.POLICY_ROOT % 'delete_tags',
|
||||
base.RULE_ADMIN_API,
|
||||
"Delete all tags for a revision.",
|
||||
[
|
||||
{
|
||||
'method': 'DELETE',
|
||||
'path': '/api/v1.0/revisions/{revision_id}/tags'
|
||||
}
|
||||
])
|
||||
]
|
||||
|
||||
|
||||
def list_rules():
|
||||
return revision_tag_policies
|
||||
Reference in New Issue
Block a user