Skip to content

Commit

Permalink
feat: implement container authentication (#119)
Browse files Browse the repository at this point in the history
This PR adds an authenticator and a token manager to support container authentication in the Python SDKs.

Co-authored-by: Phil Adams <[email protected]>
  • Loading branch information
pyrooka and padamstx authored Aug 12, 2021
1 parent e0aeed7 commit 5237277
Show file tree
Hide file tree
Showing 22 changed files with 984 additions and 31 deletions.
91 changes: 73 additions & 18 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": "package-lock.json|^.secrets.baseline$",
"lines": null
},
"generated_at": "2021-05-13T11:02:55Z",
"generated_at": "2021-08-06T15:18:39Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand All @@ -25,6 +25,7 @@
"name": "CloudantDetector"
},
{
"ghe_instance": "github.ibm.com",
"name": "GheDetector"
},
{
Expand Down Expand Up @@ -69,39 +70,39 @@
"hashed_secret": "98635b2eaa2379f28cd6d72a38299f286b81b459",
"is_secret": false,
"is_verified": false,
"line_number": 155,
"line_number": 156,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "5eb942810a75ebc850972a89285d570d484c89c4",
"is_secret": false,
"is_verified": false,
"line_number": 167,
"line_number": 168,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "4080eeeaf54faf879b9e8d99c49a8503f7e855bb",
"is_secret": false,
"is_verified": false,
"line_number": 174,
"line_number": 175,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "91dfd9ddb4198affc5c194cd8ce6d338fde470e2",
"is_secret": false,
"is_verified": false,
"line_number": 188,
"line_number": 189,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "47fcf185ee7e15fe05cae31fbe9e4ebe4a06a40d",
"is_secret": false,
"is_verified": false,
"line_number": 194,
"line_number": 195,
"type": "Secret Keyword",
"verified_result": null
}
Expand All @@ -116,6 +117,16 @@
"verified_result": null
}
],
"resources/ibm-credentials-container.env": [
{
"hashed_secret": "4e44e97dae1aa4e93c01536f48bbd8602133a86d",
"is_secret": false,
"is_verified": false,
"line_number": 8,
"type": "Secret Keyword",
"verified_result": null
}
],
"resources/ibm-credentials-cp4d.env": [
{
"hashed_secret": "5eb942810a75ebc850972a89285d570d484c89c4",
Expand Down Expand Up @@ -197,25 +208,69 @@
"hashed_secret": "da2f27d2c57a0e1ed2dc3a34b4ef02faf2f7a4c2",
"is_secret": false,
"is_verified": false,
"line_number": 113,
"line_number": 117,
"type": "Hex High Entropy String",
"verified_result": null
}
],
"test/test_container_authenticator.py": [
{
"hashed_secret": "37e94c31b6a756ba2afd2fe9a9765172cd79ac47",
"is_secret": false,
"is_verified": false,
"line_number": 65,
"type": "Secret Keyword",
"verified_result": null
}
],
"test/test_container_token_manager.py": [
{
"hashed_secret": "c8f0df25bade89c1873f5f01b85bcfb921443ac6",
"is_secret": false,
"is_verified": false,
"line_number": 14,
"type": "JSON Web Token",
"verified_result": null
},
{
"hashed_secret": "f06e1073ca9afdd800a2cf27f944d06530b5b755",
"is_secret": false,
"is_verified": false,
"line_number": 15,
"type": "JSON Web Token",
"verified_result": null
},
{
"hashed_secret": "360c23c1ac7d9d6dad1d0710606b0df9de6e1a18",
"is_secret": false,
"is_verified": false,
"line_number": 19,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "62cdb7020ff920e5aa642c3d4066950dd1f01f4d",
"is_secret": false,
"is_verified": false,
"line_number": 121,
"type": "Secret Keyword",
"verified_result": null
}
],
"test/test_cp4d_authenticator.py": [
{
"hashed_secret": "5eb942810a75ebc850972a89285d570d484c89c4",
"is_secret": false,
"is_verified": false,
"line_number": 65,
"line_number": 72,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "da2f27d2c57a0e1ed2dc3a34b4ef02faf2f7a4c2",
"is_secret": false,
"is_verified": false,
"line_number": 104,
"line_number": 111,
"type": "Hex High Entropy String",
"verified_result": null
}
Expand All @@ -225,7 +280,7 @@
"hashed_secret": "da2f27d2c57a0e1ed2dc3a34b4ef02faf2f7a4c2",
"is_secret": false,
"is_verified": false,
"line_number": 30,
"line_number": 32,
"type": "Hex High Entropy String",
"verified_result": null
}
Expand All @@ -235,23 +290,23 @@
"hashed_secret": "4080eeeaf54faf879b9e8d99c49a8503f7e855bb",
"is_secret": false,
"is_verified": false,
"line_number": 45,
"line_number": 49,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "37e94c31b6a756ba2afd2fe9a9765172cd79ac47",
"is_secret": false,
"is_verified": false,
"line_number": 68,
"line_number": 72,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "da2f27d2c57a0e1ed2dc3a34b4ef02faf2f7a4c2",
"is_secret": false,
"is_verified": false,
"line_number": 93,
"line_number": 97,
"type": "Hex High Entropy String",
"verified_result": null
}
Expand Down Expand Up @@ -287,7 +342,7 @@
"hashed_secret": "da2f27d2c57a0e1ed2dc3a34b4ef02faf2f7a4c2",
"is_secret": false,
"is_verified": false,
"line_number": 37,
"line_number": 39,
"type": "Hex High Entropy String",
"verified_result": null
}
Expand All @@ -297,29 +352,29 @@
"hashed_secret": "34a0a47a51d5bf739df0214450385e29ee7e9847",
"is_secret": false,
"is_verified": false,
"line_number": 353,
"line_number": 367,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "2863fa4b5510c46afc2bd2998dfbc0cf3d6df032",
"is_secret": false,
"is_verified": false,
"line_number": 429,
"line_number": 443,
"type": "Secret Keyword",
"verified_result": null
},
{
"hashed_secret": "b9cad336062c0dc3bb30145b1a6697fccfe755a6",
"is_secret": false,
"is_verified": false,
"line_number": 490,
"line_number": 504,
"type": "Secret Keyword",
"verified_result": null
}
]
},
"version": "0.13.1+ibm.34.dss",
"version": "0.13.1+ibm.38.dss",
"word_list": {
"file": null,
"hash": null
Expand Down
59 changes: 58 additions & 1 deletion Authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ The python-sdk-core project supports the following types of authentication:
- Bearer Token
- Identity and Access Management (IAM)
- Cloud Pak for Data
- Container
- No Authentication

The SDK user configures the appropriate type of authentication for use with service instances.
Expand Down Expand Up @@ -153,7 +154,7 @@ form:
- password: (required if apikey is not specified) the password used to obtain a bearer token.
- url: (required) The URL representing the Cloud Pak for Data token service endpoint.
- apikey: (required if password is not specified) the apikey used to obtain a bearer token.
- disableSSLVerification: (optional) A flag that indicates whether verificaton of the server's SSL
- disable_ssl_verification: (optional) A flag that indicates whether verification of the server's SSL
certificate should be disabled or not. The default value is `false`.
- headers: (optional) A set of key/value pairs that will be sent as HTTP headers in requests
made to the IAM token service.
Expand Down Expand Up @@ -202,6 +203,62 @@ authenticator = get_authenticator_from_environment('example_service')
service = ExampleService(authenticator=authenticator)
```

## Container
The `ContainerAuthenticator` is intended to be used by application code
running inside a compute resource managed by the IBM Kubernetes Service (IKS)
in which a secure compute resource token (CR token) has been stored in a file
within the compute resource's local file system.
The CR token is similar to an IAM apikey except that it is managed automatically by
the compute resource provider (IKS).
This allows the application developer to:
- avoid storing credentials in application code, configuraton files or a password vault
- avoid managing or rotating credentials

The `ContainerAuthenticator` will retrieve the CR token from
the compute resource in which the application is running, and will then perform
the necessary interactions with the IAM token service to obtain an IAM access token
using the IAM "get token" operation with grant-type `cr-token`.
The authenticator will repeat these steps to obtain a new IAM access token when the
current access token expires.
The IAM access token is added to each outbound request in the `Authorization` header in the form:
```
Authorization: Bearer <IAM-access-token>
```

### Properties
- cr_token_filename: (optional) The name of the file containing the injected CR token value. If not specified, then `/var/run/secrets/tokens/vault-token` is used as the default value. The application must have `read` permissions on the file containing the CR token value.
- iam_profile_name: (optional) The name of the linked trusted IAM profile to be used when obtaining the IAM access token (a CR token might map to multiple IAM profiles). One of `iam_profile_name` or `iam_profile_id` must be specified.
- iam_profile_id: (optional) The ID of the linked trusted IAM profile to be used when obtaining the IAM access token (a CR token might map to multiple IAM profiles). One of `iam_profile_name` or `iam_profile_id` must be specified.
- url: (optional) The URL representing the IAM token service endpoint. If not specified, a suitable default value is used.
- client_id/client_secret: (optional) The `client_id` and `client_secret` fields are used to form a "basic auth" Authorization header for interactions with the IAM token server. If neither field is specified, then no Authorization header will be sent with token server requests. These fields are optional, but must be specified together.
- disable_ssl_verification: (optional) A flag that indicates whether verification of the server's SSL certificate should be disabled or not. The default value is `False`.
- scope (optional): the scope to be associated with the IAM access token.
If not specified, then no scope will be associated with the access token.
- proxies (optional): The proxy endpoint to use for HTTP(S) requests.
- headers: (optional) A set of key/value pairs that will be sent as HTTP headers in requests made to the IAM token service.

### Programming example
```python
from ibm_cloud_sdk_core.authenticators import ContainerAuthenticatior

authenticator = ContainerAuthenticator(iam_profile_name='iam-user-123')
service = ExampleService(authenticator=authenticator)
```

### Configuration example
External configuration:
```
export EXAMPLE_SERVICE_AUTH_TYPE=container
export EXAMPLE_SERVICE_IAM_PROFILE_NAME=iam-user-123
```
Application code:
```python
from ibm_cloud_sdk_core import get_authenticator_from_environment

authenticator = get_authenticator_from_environment('example_service')
service = ExampleService(authenticator=authenticator)
```

## No Auth Authentication
The `NoAuthAuthenticator` is a placeholder authenticator which performs no actual authentication function. It can be used in situations where authentication needs to be bypassed, perhaps while developing or debugging an application or service.
### Properties
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ The python-sdk-core project supports the following types of authentication:
- Bearer Token
- Identity and Access Management (IAM)
- Cloud Pak for Data
- Container
- No Authentication

For more information about the various authentication types and how to use them with your services, click [here](Authentication.md)
Expand Down
1 change: 1 addition & 0 deletions ibm_cloud_sdk_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from .token_managers.iam_token_manager import IAMTokenManager
from .token_managers.jwt_token_manager import JWTTokenManager
from .token_managers.cp4d_token_manager import CP4DTokenManager
from .token_managers.container_token_manager import ContainerTokenManager
from .api_exception import ApiException
from .utils import datetime_to_string, string_to_datetime, read_external_sources
from .utils import datetime_to_string_list, string_to_datetime_list
Expand Down
1 change: 1 addition & 0 deletions ibm_cloud_sdk_core/authenticators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from .authenticator import Authenticator
from .basic_authenticator import BasicAuthenticator
from .bearer_token_authenticator import BearerTokenAuthenticator
from .container_authenticator import ContainerAuthenticator
from .cp4d_authenticator import CloudPakForDataAuthenticator
from .iam_authenticator import IAMAuthenticator
from .no_auth_authenticator import NoAuthAuthenticator
Loading

0 comments on commit 5237277

Please sign in to comment.