Remove the project-id from Barbican resource URIs¶
https://blueprints.launchpad.net/barbican/+spec/api-remove-uri-tenant-id
OpenStack projects appear to be moving away from requiring a project-id in the URI, as this is redundant information when Keystone authentication is used. All Barbican resource URIs includes project-id as part of their URI. This need to be reviewed.
Problem Description¶
All Barbican resources have a project-id in their URI. This helps to correlate the resource with the specified tenant when no external authentication mechanism is used.
However, all Barbican deployments would use Keystone to authenticate the API requests. With Keystone, the project-id information is already obtained when the X-Auth-Token header from the request is validated. This makes the project-id in the URI redundant.
Need a solution to remove the project-id from the URI.
Proposed Change¶
All Barbican resource URIs will drop project-id from their URI. For example,
/v1/<project-id>/secrets
will become/v1/secrets
,/v1/<project-id>/secrets/<secret-ref>
will become/v1/secrets/<secret-ref>
and so on.For all successfully authenticated client requests, the project-id (a.k.a tenant-id) would be obtained by looking up the authentication context associated with the request. If it is not found (unscoped token), the request will be denied with a HTTP 401 error.
If no authentication mechanism has been configured with the Barbican deployment, the client is expected to pass in a “X-Project-Id” request header, set to the desired project-id. If this header is not passed in, the request will be denied with a HTTP 400 error. In other words, the client is expected to spoof the data presented to Barbican by
keystone.middleware.auth_token
, which Barbican trusts.
Backwards compatability note:
Once the changes proposed by this spec are in place, callers of the API should no longer specify project-id in the URI. Otherwise, the request will be denied with a HTTP 404 error.
Alternatives¶
None.
Data model impact¶
None.
REST API impact¶
All Barbican REST resources will be impacted by this change. However, this change is limited to
dropping the project-id from the uri. All other request parameters (including limit and filter
parameters) will remain the same. If Barbican is configured for unauthenticated request flow,
then X-Project-Id
is required to be passed by the caller.
API¶
Secrets
Create Secret: POST /v1/secrets
Example:
Request:
Headers:
X-Auth-Token:<token>
Content-Type:application/json
POST /v1/secrets
{
"name": "AES key",
"expiration": "2014-02-28T19:14:44.180394",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc",
"payload": "gF6+lLoF3ohA9aPRpt+6bQ==",
"payload_content_type": "application/octet-stream",
"payload_content_encoding": "base64"
}
Response:
Status: 201 Created
{
"secret_ref": "http://localhost:9311/v1/secrets/a8957047-16c6-4b05-ac57-8621edd0e9ee"
}
Two-step secret creation: PUT /v1/secrets/<secret-id>
Example:
Request:
Headers:
X-Auth-Token:<token>
Content-Type:text/plain
PUT /v1/secrets/a8957047-16c6-4b05-ac57-8621edd0e9ee
'mysecret'
Response:
Status: 201 Created
{
"secret_ref": "http://localhost:9311/v1/secrets/a8957047-16c6-4b05-ac57-8621edd0e9ee"
}
List Secrets: GET /v1/secrets
Example:
Request:
Headers:
X-Auth-Token:<token>
GET /v1/secrets
Response:
Status: 200 Ok
{
"secrets": [
{
"status": "ACTIVE",
"updated": "2013-06-28T15:23:30.668641",
"mode": "cbc",
"name": "Main Encryption Key",
"algorithm": "AES",
"created": "2013-06-28T15:23:30.668619",
"secret_ref": "http://localhost:9311/v1/secrets/e171bb2d-f14f-433e-84f0-3dfcac7a7311",
"expiration": "2014-06-28T15:23:30.668619",
"bit_length": 256,
"content_types": {
"default": "application/octet-stream"
}
},
{
"status": "ACTIVE",
"updated": "2013-06-28T15:23:32.210474",
"mode": "cbc",
"name": "Backup Key",
"algorithm": "AES",
"created": "2013-06-28T15:23:32.210467",
"secret_ref": "http://localhost:9311/v1/secrets/6dba7827-c232-4a2b-8f3d-f523ca3a3f99",
"expiration": null,
"bit_length": 256,
"content_types": {
"default": "application/octet-stream"
}
},
{
"status": "ACTIVE",
"updated": "2013-06-28T15:23:33.092660",
"mode": null,
"name": "PostgreSQL admin password",
"algorithm": null,
"created": "2013-06-28T15:23:33.092635",
"secret_ref": "http://localhost:9311/v1/secrets/6dfa448d-c35a-4158-abaf-e4c249efb580",
"expiration": null,
"bit_length": null,
"content_types": {
"default": "text/plain"
}
}
],
"next": "http://localhost:9311/v1/secrets?limit=3&offset=5",
"previous": "http://localhost:9311/v1/secrets?limit=3&offset=0"
}
Get individual secret: GET /v1/secrets/<secret-id>
Example:
Request:
Headers:
X-Auth-Token:<token>
GET /v1/secrets/e171bb2d-f14f-433e-84f0-3dfcac7a7311
Response:
Status: 200 Ok
{
"status": "ACTIVE",
"updated": "2013-06-28T15:23:30.668641",
"mode": "cbc",
"name": "Main Encryption Key",
"algorithm": "AES",
"secret_ref": "http://localhost:9311/v1/secrets/e171bb2d-f14f-433e-84f0-3dfcac7a7311",
"expiration": "2014-06-28T15:23:30.668619",
"bit_length": 256,
"content_types": {
"default": "application/octet-stream"
}
}
Delete individual secret: DELETE /v1/secrets/<secret-id>
Example:
Request:
Headers:
X-Auth-Token:<token>
DELETE /v1/secrets/e171bb2d-f14f-433e-84f0-3dfcac7a7311
Response:
Status: 204 No Content
Create Secret(no authentication) : POST /v1/secrets
Example:
Request:
Headers:
X-Project-Id:<project-id>
Content-Type:application/json
POST /v1/secrets
{
"name": "AES key",
"expiration": "2014-02-28T19:14:44.180394",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc",
"payload": "gF6+lLoF3ohA9aPRpt+6bQ==",
"payload_content_type": "application/octet-stream",
"payload_content_encoding": "base64"
}
Response:
Status: 201 Created
{
"secret_ref": "http://localhost:9311/v1/secrets/a8957047-16c6-4b05-ac57-8621edd0e9ee"
}
Orders
Create Order: POST /v1/orders
Example:
Request:
Headers:
X-Auth-Token:<token>
Content-Type:application/json
POST /v1/orders
{
"secret": {
"name": "secretname",
"algorithm": "AES",
"bit_length": 256,
"mode": "cbc",
"payload_content_type": "application/octet-stream"
}
}
Response:
Status: 201 Created
{
"order_ref": "http://localhost:9311/v1/orders/a8957047-16c6-4b05-ac57-8621edd0e9ee"
}
Get individual order: GET /v1/orders/<order-id>
Example:
Request:
Headers:
X-Auth-Token:<token>
GET /v1/orders/f9b633d8-fda5-4be8-b42c-5b2c9280289e
Response:
Status: 200 Ok
{
"secret": {
"name": "secretname",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc",
"payload_content_type": "application/octet-stream"
},
"order_ref": "http://localhost:8080/v1/orders/f9b633d8-fda5-4be8-b42c-5b2c9280289e",
"secret_ref": "http://localhost:8080/v1/secrets/888b29a4-c7cf-49d0-bfdf-bd9e6f26d718",
"status": "ERROR",
"error_status_code": "400 Bad Request",
"error_reason": "Secret creation issue seen - content-encoding of 'bogus' not supported."
}
Get list of orders per tenant: GET /v1/orders
Example:
Request:
Headers:
X-Auth-Token:<token>
GET /v1/orders
Response:
Status: 200 Ok
{
"orders": [
{
"status": "ACTIVE",
"secret_ref": "http://localhost:9311/v1/secrets/bf2b33d5-5347-4afb-9009-b4597f415b7f",
"updated": "2013-06-28T18:29:37.058718",
"created": "2013-06-28T18:29:36.001750",
"secret": {
"name": "secretname",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc",
"payload_content_type": "application/octet-stream"
},
"order_ref": "http://localhost:9311/v1/orders/3100078a-6ab1-4c3f-ab9f-295938c91733"
},
{
"status": "ACTIVE",
"secret_ref": "http://localhost:9311/v1/secrets/fa71b143-f10e-4f7a-aa82-cc292dc33eb5",
"updated": "2013-06-28T18:29:37.058718",
"created": "2013-06-28T18:29:36.001750",
"secret": {
"name": "secretname",
"algorithm": "aes",
"bit_length": 256,
"mode": "cbc",
"payload_content_type": "application/octet-stream"
},
"order_ref": "http://localhost:9311/v1/orders/30b3758a-7b8e-4f2c-b9f0-f590c6f8cc6d"
}
]
}
Delete individual order: DELETE /v1/orders/<order-id>
Example:
Request:
Headers:
X-Auth-Token:<token>
DELETE /v1/orders/e171bb2d-f14f-433e-84f0-3dfcac7a7311
Response:
Status: 204 No Content
Containers
Create Container: POST /v1/containers
Example:
Request:
Headers:
X-Auth-Token:<token>
Content-Type:application/json
POST /v1/containers
{
"name": "container name",
"type": "rsa",
"secret_refs": [
{
"name": "private_key",
"secret_ref":"http://localhost:9311/v1/secrets/05a47308-d045-43d6-bfe3-1dbcd0c3a97b"
},
{
"name": "public_key",
"secret_ref":"http://localhost:9311/v1/secrets/05a47308-d045-43d6-bfe3-1dbcd0c3a97b"
},
{
"name": "private_key_passphrase",
"secret_ref":"http://localhost:9311/v1/secrets/05a47308-d045-43d6-bfe3-1dbcd0c3a97b"
}
]
}
Response:
Status: 201 Created
{
"container_ref": "http://localhost:9311/v1/containers/a8957047-16c6-4b05-ac57-8621edd0e9ee"
}
Get individual container: GET /v1/containers/<container-id>
Example:
Request:
Headers:
X-Auth-Token:<token>
GET /v1/containers/f9b633d8-fda5-4be8-b42c-5b2c9280289e
Response:
Status: 200 Ok
{
"name":"rsa container",
"secret_refs":[
{
"secret_ref":"http://localhost:9311/v1/secrets/059805d5-b400-47da-abc5-cae7286d3ede",
"name":"private_key_passphrase"
},
{
"secret_ref":"http://localhost:9311/v1/secrets/28704f0f-3273-40d4-bc40-4de2691135ea",
"name":"private_key"
},
{
"secret_ref":"http://localhost:9311/v1/secrets/29d89344-10ad-4f92-8aa2-adebaf7556ee",
"name":"public_key"
}
],
"container_ref":"http://localhost:9311/v1/containers/888b29a4-c7cf-49d0-bfdf-bd9e6f26d718",
"type":"rsa"
}
Get list of containers per tenant: GET /v1/containers
Example:
Request:
Headers:
X-Auth-Token:<token>
GET /v1/containers
Response:
Status: 200 Ok
{
"total":42,
"containers":[
{
"status":"ACTIVE",
"updated":"2014-02-11T18:05:58.909411",
"name":"generic container_updated",
"secret_refs":[
{
"secret_id":"123",
"name":"private_key"
},
{
"secret_id":"321",
"name":"public_key"
},
{
"secret_id":"456",
"name":"private_key_passphrase"
}
],
"created":"2014-02-11T18:05:58.909403",
"container_ref":"http://localhost:9311/v1/containers/d4e06015-4f6e-4626-ac3d-4ece6621f96d",
"type":"rsa"
},
{
"status":"ACTIVE",
"updated":"2014-02-11T18:08:58.160557",
"name":"generic container_updated",
"secret_refs":[
{
"secret_id":"321",
"name":"public_key"
},
{
"secret_id":"456",
"name":"private_key_passphrase"
}
],
"created":"2014-02-11T18:08:58.160551",
"container_ref":"http://localhost:9311/v1/containers/bb24fa61-0b5f-4d40-8990-846e95cd7b12",
"type":"rsa"
},
{
"status":"ACTIVE",
"updated":"2014-02-11T18:25:58.198072",
"name":"generic container_updated",
"secret_refs":[
{
"secret_id":"1df433d6-c2d4-480d-90fb-0bfd9c5da3dd",
"name":"private_key"
},
{
"secret_id":"321",
"name":"public_key"
},
{
"secret_id":"456",
"name":"private_key_passphrase"
}
],
"created":"2014-02-11T18:25:58.198063",
"container_ref":"http://localhost:9311/v1/containers/38f58696-5013-4bd6-ab2b-fbea41dc957a",
"type":"rsa"
},
{
"status":"ACTIVE",
"updated":"2014-02-11T18:44:06.296957",
"name":"generic container_updated",
"secret_refs":[
{
"secret_id":"1df433d6-c2d4-480d-90fb-0bfd9c5da3dd",
"name":"private_key"
},
{
"secret_id":"321",
"name":"public_key"
},
{
"secret_id":"456",
"name":"private_key_passphrase"
}
],
"created":"2014-02-11T18:44:06.296947",
"container_ref":"http://localhost:9311/v1/containers/a8d1adfd-0d36-4eb0-8762-99787eb4a7ff",
"type":"rsa"
}
],
"next":"http://localhost:9311/v1/containers?limit=10&offset=10"
}
Delete individual container: DELETE /v1/containers/<container-id>
Example:
Request:
Headers:
X-Auth-Token:<token>
DELETE /v1/containers/e171bb2d-f14f-433e-84f0-3dfcac7a7311
Response:
Status: 204 No Content
Security impact¶
This change will require that all requests have a valid keystone token which will be used for authorization.
Requests without the token will be considered as unauthenticated requests.
Notifications & Audit Impact¶
None.
Other end user impact¶
Barbican python client will need to be modified to accommodate API changes. This work could happen in parallel to the server side tasks.
Performance Impact¶
None.
Other deployer impact¶
None.
Developer impact¶
None.
Implementation¶
Assignee(s)¶
Venkat Sundaram (tsv)
Work Items¶
Modify PecanAPI routing mechanism and remove logic that parses project-id from the URI (tsv)
Enhance the enforce_rback decorator for the controllers to get the keystone_id from the authentication context if it is not passed in(tsv)
Update the barbican/common/util module method hostname_for_refs to strip project-id from the URI links returned in response body(tsv)
Modify barbican client and replace all tenant-id references from the URI it calls (tsv)
Enhance the tests (tsv)
Dependencies¶
None.
Testing¶
Update unit tests to drop project-id from uri.
Tempest tests need to be added for functional testing
Documentation Impact¶
Existing documentation has to be updated to remove the project-id from the uri.
Explain how to specify project-id when no authentication mechanism is used.