-
Notifications
You must be signed in to change notification settings - Fork 8
Temporary object store credentials endpoint #544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
hardbyte
merged 8 commits into
develop
from
temporary-object-store-credentials-endpoint
Apr 21, 2020
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
853fabd
Endpoint for creating temporary object store credentials via assume-role
hardbyte 2fc6b5d
Use latest versions of minio
hardbyte 04ee7e2
Explicitly initialize the object store during azure integration tests
hardbyte fe679ff
Initialise object store to handle uploads during kubernetes deployment
hardbyte f2176e8
Fix k8s deployment of init object store job
hardbyte 75d07cf
Use newer version of minio for k8s deployment
hardbyte 8a569fd
Testing fixes
hardbyte bf97dd5
Update based on feedback
hardbyte File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,13 +8,15 @@ | |
| # descriptions. | ||
| openapi: 3.0.0 | ||
| info: | ||
| version: '1.3' | ||
| version: '1.13' | ||
| title: Entity Matching API | ||
| x-logo: | ||
| url: http://clkhash.readthedocs.io/en/latest/_static/logo.svg | ||
| contact: | ||
| name: 'Confidential Computing, Data61 | CSIRO' | ||
| email: [email protected] | ||
| url: https://github.com/data61/anonlink-entity-service | ||
|
|
||
| description: >- | ||
| Allows multiple organisations to carry out private record linkage - | ||
| without disclosing personally identifiable information. | ||
|
|
@@ -86,6 +88,8 @@ info: | |
| servers: | ||
| - url: https://anonlink.easd.data61.xyz/api/v1 | ||
| description: default EASD cluster | ||
| - url: http://localhost:8851/api/v1 | ||
| description: Local deployment | ||
|
|
||
| paths: | ||
| /status: | ||
|
|
@@ -276,6 +280,44 @@ paths: | |
| '503': | ||
| $ref: '#/components/responses/RateLimited' | ||
|
|
||
| '/projects/{project_id}/authorize-external-upload': | ||
| get: | ||
| operationId: entityservice.views.objectstore.authorize_external_upload | ||
| summary: Retrieve temporary objest store credentials for uploading data | ||
| tags: | ||
| - Project | ||
| description: | | ||
| Returns a set of temporary security credentials that the client can use to upload data to the | ||
| object store. | ||
|
|
||
| A valid **upload token** is required to authorise this call. The returned *Temporary Object | ||
| Store Credentials* can be used with any S3 compatible client. For example by using `boto3` in | ||
| Python. The returned credentials are restricted to allow only uploading data to a particular path | ||
| in a particular bucket for a finite period (defaulting to 12 hours). | ||
|
|
||
| Note this feature may be disabled by the administrator, in this case the endpoint will return a | ||
| `500` server error. | ||
| parameters: | ||
| - $ref: '#/components/parameters/project_id' | ||
| - $ref: '#/components/parameters/token' | ||
| responses: | ||
| '201': | ||
| description: Temporary Object Store Credentials | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/ObjectStoreCredentials' | ||
| '400': | ||
| $ref: '#/components/responses/BadRequest' | ||
| '403': | ||
| $ref: '#/components/responses/Unauthorized' | ||
| '404': | ||
| $ref: '#/components/responses/NotFound' | ||
| '500': | ||
| $ref: '#/components/responses/Error' | ||
| '503': | ||
| $ref: '#/components/responses/RateLimited' | ||
|
|
||
| '/projects/{project_id}/clks': | ||
| post: | ||
| operationId: entityservice.views.project.project_clks_post | ||
|
|
@@ -327,12 +369,6 @@ paths: | |
| oneOf: | ||
| - $ref: '#/components/schemas/CLKUpload' | ||
| - $ref: '#/components/schemas/CLKnBlockUpload' | ||
| # unfortunately connexion can not handle multiple different encoding types on an endpoint. | ||
| #application/octet-stream: | ||
| # schema: | ||
| # type: string | ||
| # format: binary | ||
|
|
||
| responses: | ||
| '201': | ||
| description: Data Uploaded | ||
|
|
@@ -833,7 +869,7 @@ components: | |
| minimum: 0 | ||
| description: | ||
| type: string | ||
| description: oportunity to give those numbers some context, what are we counting here? | ||
| description: opportunity to give those numbers some context, what are we counting here? | ||
| relative: | ||
| type: number | ||
| format: double | ||
|
|
@@ -1076,3 +1112,37 @@ components: | |
| type: string | ||
| message: | ||
| type: string | ||
|
|
||
| ObjectStoreCredentials: | ||
| description: Temporary credentials allowing client to upload a file to an object store. | ||
| type: object | ||
| properties: | ||
| upload: | ||
| description: | | ||
| Configuration of object store to upload file/s to. Specifies the server, bucket and | ||
| the approved path. The attached credentials are restricted to only allow uploads to | ||
| this path. | ||
| type: object | ||
| properties: | ||
| endpoint: | ||
| type: string | ||
| description: Hostname, and port of object store. E.g. minio.anonlink.example.com:9000 | ||
| bucket: | ||
| type: string | ||
| description: Target bucket | ||
| path: | ||
| type: string | ||
| description: Target path | ||
|
|
||
| credentials: | ||
| description: Object Store credentials (compatible with both AWS & MinIO) | ||
| type: object | ||
| properties: | ||
| AccessKeyId: | ||
| type: string | ||
| SecretAccessKey: | ||
| type: string | ||
| Expiration: | ||
| type: string | ||
| SessionToken: | ||
hardbyte marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| type: string | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
backend/entityservice/integrationtests/objectstoretests/conftest.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import os | ||
| from time import sleep | ||
|
|
||
| import minio | ||
| import pytest | ||
|
|
||
| from entityservice.settings import Config as config | ||
|
|
||
| @pytest.fixture(scope='session') | ||
| def upload_restricted_minio_client(): | ||
|
|
||
| sleep(int(os.getenv('INITIAL_DELAY', '5'))) | ||
|
|
||
| restricted_mc_client = minio.Minio( | ||
| config.UPLOAD_OBJECT_STORE_SERVER, | ||
| config.UPLOAD_OBJECT_STORE_ACCESS_KEY, | ||
| config.UPLOAD_OBJECT_STORE_SECRET_KEY, | ||
| region='us-east-1', | ||
| secure=False | ||
| ) | ||
| restricted_mc_client.set_app_info("anonlink-restricted", "testing client") | ||
| return restricted_mc_client |
70 changes: 70 additions & 0 deletions
70
backend/entityservice/integrationtests/objectstoretests/test_objectstore.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| """ | ||
| Testing: | ||
| - uploading over existing files | ||
| - using deleted credentials | ||
| - using expired credentials | ||
|
|
||
| """ | ||
| import io | ||
|
|
||
| import minio | ||
| from minio import Minio | ||
| import pytest | ||
| from minio.credentials import AssumeRoleProvider, Credentials | ||
|
|
||
| from entityservice.object_store import connect_to_object_store, connect_to_upload_object_store | ||
| from entityservice.settings import Config | ||
|
|
||
| restricted_upload_policy = """{ | ||
| "Version": "2012-10-17", | ||
| "Statement": [ | ||
| { | ||
| "Action": [ | ||
| "s3:PutObject" | ||
| ], | ||
| "Effect": "Allow", | ||
| "Resource": [ | ||
| "arn:aws:s3:::uploads/2020/*" | ||
| ], | ||
| "Sid": "Upload-access-to-specific-bucket-only" | ||
| } | ||
| ] | ||
| } | ||
| """ | ||
|
|
||
|
|
||
| class TestAssumeRole: | ||
|
|
||
| def test_temp_credentials_minio(self): | ||
|
|
||
| upload_endpoint = Config.UPLOAD_OBJECT_STORE_SERVER | ||
| bucket_name = "uploads" | ||
|
|
||
| root_mc_client = connect_to_object_store() | ||
| upload_restricted_minio_client = connect_to_upload_object_store() | ||
| if not root_mc_client.bucket_exists(bucket_name): | ||
| root_mc_client.make_bucket(bucket_name) | ||
|
|
||
| with pytest.raises(minio.error.AccessDenied): | ||
| upload_restricted_minio_client.list_buckets() | ||
|
|
||
| # Should be able to put an object though | ||
| upload_restricted_minio_client.put_object(bucket_name, 'testobject', io.BytesIO(b'data'), length=4) | ||
|
|
||
| credentials_provider = AssumeRoleProvider(upload_restricted_minio_client, | ||
| Policy=restricted_upload_policy | ||
| ) | ||
| temp_creds = Credentials(provider=credentials_provider) | ||
|
|
||
| newly_restricted_mc_client = Minio(upload_endpoint, credentials=temp_creds, region='us-east-1', secure=False) | ||
|
|
||
| with pytest.raises(minio.error.AccessDenied): | ||
| newly_restricted_mc_client.list_buckets() | ||
|
|
||
| # Note this put object worked with the earlier credentials | ||
| # But should fail if we have applied the more restrictive policy | ||
| with pytest.raises(minio.error.AccessDenied): | ||
| newly_restricted_mc_client.put_object(bucket_name, 'testobject2', io.BytesIO(b'data'), length=4) | ||
|
|
||
| # this path is allowed in the policy however | ||
| newly_restricted_mc_client.put_object(bucket_name, '2020/testobject', io.BytesIO(b'data'), length=4) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.