Skip to content

Commit 7b9bb1c

Browse files
authored
Merge pull request #79 from DelineaXPM/main.platfor_support.sw
Add platform authentication support to access Secret Server API
2 parents 38719f8 + 2c68a71 commit 7b9bb1c

7 files changed

Lines changed: 321 additions & 46 deletions

File tree

.github/workflows/run_tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,6 @@ jobs:
3434
TSS_SECRET_PATH: ${{ secrets.TSS_SECRET_PATH }}
3535
TSS_FOLDER_ID: ${{ secrets.TSS_FOLDER_ID }}
3636
TSS_FOLDER_PATH: ${{ secrets.TSS_FOLDER_PATH }}
37+
TSS_PLATFORM_USERNAME: ${{ secrets.TSS_PLATFORM_USERNAME }}
38+
TSS_PLATFORM_PASSWORD: ${{ secrets.TSS_PLATFORM_PASSWORD }}
39+
TSS_PLATFORM_BASE_URL: ${{ secrets.TSS_PLATFORM_BASE_URL }}

README.md

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
![PyPI Version](https://img.shields.io/pypi/v/python-tss-sdk) ![License](https://img.shields.io/github/license/DelineaXPM/python-tss-sdk) ![Python Versions](https://img.shields.io/pypi/pyversions/python-tss-sdk)
77

8-
The [Delinea](https://delinea.com/) [Secret Server](https://delinea.com/products/secret-server/) Python SDK contains classes that interact with Secret Server via the REST API.
8+
9+
The [Delinea](https://delinea.com/) [Secret Server](https://delinea.com/products/secret-server/) Python SDK contains classes that interact with Secret Server via their REST APIs.
10+
11+
## Authentication Support
12+
13+
This SDK supports both Secret Server and Platform authentication. You can use the same authorizer classes for both systems and instantiate either a Secret Server or Platform client as needed. For Secret Server, you need to create an application user with the required permissions for authentication. For Platform, you need to create a service user with the appropriate permissions for authentication.
914

1015
## Install
1116

@@ -26,17 +31,26 @@ There are three ways in which you can authorize the `SecretServer` and `SecretSe
2631

2732
#### Password Authorization
2833

29-
If using traditional `username` and `password` authentication to log in to your Secret Server, you can pass the `PasswordGrantAuthorizer` into the `SecretServer` class at instantiation. The `PasswordGrantAuthorizer` requires a `base_url`, `username`, and `password`. It optionally takes a `token_path_uri`, but defaults to `/oauth2/token`.
34+
If using traditional `username` and `password` authentication to log in to your Secret Server either directly or through Platform, you can pass the `PasswordGrantAuthorizer` into the `SecretServer` class at instantiation. The `PasswordGrantAuthorizer` requires a `base_url`, `username`, and `password`. It optionally takes a `token_path_uri`, but defaults to `/oauth2/token` or `/identity/api/oauth2/token/xpmplatform`, depending on whether a secret server or platform is used for authentication.
3035

36+
##### With Secret Server
3137
```python
3238
from delinea.secrets.server import PasswordGrantAuthorizer
3339

3440
authorizer = PasswordGrantAuthorizer("https://hostname/SecretServer", os.getenv("myusername"), os.getenv("password")")
3541
```
3642

43+
##### With Platform
44+
45+
```python
46+
from delinea.secrets.server import PasswordGrantAuthorizer
47+
48+
authorizer = PasswordGrantAuthorizer("https://platform.delinea.app", os.getenv("myusername"), os.getenv("password"))
49+
```
50+
3751
#### Domain Authorization
3852

39-
To use a domain credential, use the `DomainPasswordGrantAuthorizer`. It requires a `base_url`, `username`, `domain`, and `password`. It optionally takes a `token_path_uri`, but defaults to `/oauth2/token`.
53+
To use a domain credential, use the `DomainPasswordGrantAuthorizer`. It requires a `base_url`, `username`, `domain`, and `password`. It optionally takes a `token_path_uri`, but defaults to `/oauth2/token`. It is applicable only when authentication is done using a secret server.
4054

4155
```python
4256
from delinea.secrets.server import DomainPasswordGrantAuthorizer
@@ -46,7 +60,7 @@ authorizer = DomainPasswordGrantAuthorizer("https://hostname/SecretServer", os.g
4660

4761
#### Access Token Authorization
4862

49-
If you already have an `access_token`, you can pass directly via the `AccessTokenAuthorizer`.
63+
If you already have an `access_token` of Secret Server or Platform user, you can pass directly via the `AccessTokenAuthorizer`.
5064

5165
```python
5266
from delinea.secrets.server import AccessTokenAuthorizer
@@ -56,14 +70,15 @@ authorizer = AccessTokenAuthorizer("AgJ1slfZsEng9bKsssB-tic0Kh8I...")
5670

5771
## Secret Server Cloud
5872

59-
The SDK API requires an `Authorizer` and a `tenant`.
73+
The SDK API requires an `Authorizer` and either a `tenant` or a `base_url`. In the case of plaform authentication, only a `base_url` is supported.
6074

6175
`tenant` simplifies the configuration when using Secret Server Cloud by assuming the default folder structure and creating the _base URL_ from a template that takes the `tenant` and an optional top-level domain (TLD) that defaults to `com`, as parameters.
6276

6377
### Useage
6478

65-
Instantiate the `SecretServerCloud` class with `tenant` and an `Authorizer` (optionally include a `tld`). To retrieve a secret, pass an integer `id` to `get_secret()` which will return the secret as a JSON encoded string.
79+
Instantiate the `SecretServerCloud` class with `tenant` or `base_url`, along with an `Authorizer` (when providing `tenant`, yoou may optionally include a `tld`). To retrieve a secret, pass an integer `id` to `get_secret()` which will return the secret as a JSON encoded string.
6680

81+
##### With Secret Server
6782
```python
6883
from delinea.secrets.server import SecretServerCloud
6984

@@ -76,6 +91,20 @@ serverSecret = ServerSecret(**secret)
7691
print(f"username: {serverSecret.fields['username'].value}\npassword: {serverSecret.fields['password'].value}")
7792
```
7893

94+
##### With Platform
95+
96+
```python
97+
from delinea.secrets.server import SecretServerCloud
98+
99+
secret_server = SecretServerCloud(authorizer=authorizer, base_url="https://platform.delinea.app")
100+
101+
secret = secret_server.get_secret(os.getenv("TSS_SECRET_ID"))
102+
103+
serverSecret = ServerSecret(**secret)
104+
105+
print(f"username: {serverSecret.fields['username'].value}\npassword: {serverSecret.fields['password'].value}")
106+
```
107+
79108
The SDK API also contains a `Secret` `@dataclass` containing a subset of the Secret's attributes and a dictionary of all the fields keyed by the Secret's `slug`.
80109

81110
## Initializing SecretServer
@@ -86,12 +115,21 @@ The SDK API also contains a `Secret` `@dataclass` containing a subset of the Sec
86115

87116
To instantiate the `SecretServer` class, it requires a `base_url`, an `Authorizer` object (see above), and an optional `api_path_uri` (defaults to `"/api/v1"`)
88117

118+
##### With Secret Server
89119
```python
90120
from delinea.secrets.server import SecretServer
91121

92122
secret_server = SecretServer("https://hostname/SecretServer", authorizer=authorizer)
93123
```
94124

125+
##### With Platform
126+
127+
```python
128+
from delinea.secrets.server import SecretServer
129+
130+
secret_server = SecretServer(base_url="https://platform.delinea.app", authorizer=authorizer)
131+
```
132+
95133
Secrets can be fetched using the `get_secret` method, which takes an integer `id` of the secret and, returns a `json` object:
96134

97135
```python

conftest.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ def env_vars():
1919
}
2020

2121

22+
@pytest.fixture
23+
def platform_env_vars():
24+
return {
25+
"platform_username": os.getenv("TSS_PLATFORM_USERNAME"),
26+
"platform_password": os.getenv("TSS_PLATFORM_PASSWORD"),
27+
"platform_base_url": os.getenv("TSS_PLATFORM_BASE_URL"),
28+
"secret_id": os.getenv("TSS_SECRET_ID"),
29+
"secret_path": os.getenv("TSS_SECRET_PATH"),
30+
"folder_id": os.getenv("TSS_FOLDER_ID"),
31+
"folder_path": os.getenv("TSS_FOLDER_PATH"),
32+
}
33+
34+
2235
@pytest.fixture
2336
def authorizer(env_vars):
2437
return PasswordGrantAuthorizer(
@@ -28,6 +41,24 @@ def authorizer(env_vars):
2841
)
2942

3043

44+
@pytest.fixture
45+
def platform_authorizer(platform_env_vars):
46+
from delinea.secrets.server import PasswordGrantAuthorizer
47+
48+
return PasswordGrantAuthorizer(
49+
platform_env_vars["platform_base_url"],
50+
platform_env_vars["platform_username"],
51+
platform_env_vars["platform_password"],
52+
)
53+
54+
3155
@pytest.fixture
3256
def secret_server(env_vars, authorizer):
3357
return SecretServerCloud(env_vars["tenant"], authorizer)
58+
59+
60+
@pytest.fixture
61+
def platform_server(platform_env_vars, platform_authorizer):
62+
from delinea.secrets.server import SecretServer
63+
64+
return SecretServer(platform_env_vars["platform_base_url"], platform_authorizer)

delinea/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""The Delinea Secret Server Python SDK"""
22

3-
__version__ = "1.2.3"
3+
__version__ = "2.0.0"

0 commit comments

Comments
 (0)