Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,25 @@ on:
branches:
- main

# Default to read-only; the lint job below grants itself the write scopes
# lint-action actually needs (auto-fix commits + check-run annotations).
permissions:
contents: read

jobs:
lint:
name: Run black linter
runs-on: ubuntu-latest
permissions:
contents: write # auto_fix: true pushes formatting commits back to the branch
checks: write # lint-action publishes results as a check run
steps:
- name: Check out Git repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
- name: Install Python dependencies
run: pip install black
run: pip install black==26.5.1 # match the pin in requirements-dev.txt
- name: Run black
uses: wearerequired/lint-action@548d8a7c4b04d3553d32ed5b6e91eb171e10e7bb # v2
with:
Expand Down
24 changes: 18 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ on:
tags:
- 'v*'

permissions:
contents: read

jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
# Required for PyPI Trusted Publishing (OIDC) below; no PYPI_API_TOKEN
# secret is used or needed once a trusted publisher is configured.
id-token: write

steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
Expand All @@ -18,14 +26,18 @@ jobs:

- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flit
python -m pip install --upgrade "pip>=26.2" # CVE-2026-8643, CVE-2026-6357, CVE-2026-13346, CVE-2026-3219
python -m pip install flit==3.12.0 # match flit_core pin in pyproject.toml

- name: Build package
run: flit build

- name: Publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
# SECURITY_REVIEW.md SDK-5 / DevPlan.md 3.3: migrated from a long-lived
# PYPI_API_TOKEN to PyPI Trusted Publishing (OIDC), and the action ref
# is now SHA-pinned (it was previously the mutable `release/v1` branch).
# REQUIRES: a trusted publisher for this repo + workflow file must be
# configured on pypi.org (project Settings -> Publishing) before this
# tag push will succeed. Coordinate with the PyPI project owner first;
# keep the PYPI_API_TOKEN repo secret until that is confirmed working.
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
8 changes: 7 additions & 1 deletion .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ name: Run Tests

on: [pull_request]

# This workflow only checks out code and runs the test suite; it never
# writes to the repo or opens PRs/issues, so read-only is sufficient.
permissions:
contents: read

jobs:

build:
runs-on: ubuntu-latest
environment: testing
strategy:
matrix:
python: [3.8, 3.9, "3.10", "3.11"]
# Python 3.8/3.9 dropped: fixed requests/urllib3 pins require Python >= 3.10 (work item 741117)
python: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
Expand Down
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ There are three ways in which you can authorize the `SecretServer` and `SecretSe

#### Password Authorization

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.
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. It also optionally takes a `server_type` (`"secret_server"` or `"platform"`) to skip automatic server-type detection — see [Server-Type Detection](#server-type-detection).

##### With Secret Server
```python
Expand All @@ -50,7 +50,7 @@ authorizer = PasswordGrantAuthorizer("https://platform.delinea.app", os.getenv("

#### Domain Authorization

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.
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`, and a `server_type` (see [Server-Type Detection](#server-type-detection)). It is applicable only when authentication is done using a secret server.

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

#### Access Token Authorization

If you already have an `access_token` of Secret Server or Platform user, you can pass directly via the `AccessTokenAuthorizer`. The `AccessTokenAuthorizer` requires a `access_token` and `base_url`.
If you already have an `access_token` of Secret Server or Platform user, you can pass directly via the `AccessTokenAuthorizer`. The `AccessTokenAuthorizer` requires a `access_token` and `base_url`. It optionally takes a `server_type` (see [Server-Type Detection](#server-type-detection)).

##### With Secret Server
```python
Expand All @@ -77,6 +77,25 @@ from delinea.secrets.server import AccessTokenAuthorizer
authorizer = AccessTokenAuthorizer("AgJ1slfZsEng9bKsssB-tic0Kh8I...", "https://platform.delinea.app")
```

#### Server-Type Detection

By default every authorizer automatically detects whether the `base_url` points at a Secret Server or a Platform instance by probing its health-check endpoints (`/api/v1/healthcheck` then `/health`). The result is cached per `base_url` for the lifetime of the process, so the probe pair fires only once per `base_url`.

You can skip detection entirely by passing an explicit `server_type` of either `"secret_server"` or `"platform"`. When supplied, no health-check probe is issued. This is recommended for callers that run each lookup in a fresh, short-lived process (for example, some Ansible lookup-plugin runtimes), where a fresh process cannot benefit from the in-process cache and the repeated unauthenticated probes can be rate-limited to `403` by the Delinea Platform WAF.

```python
from delinea.secrets.server import AccessTokenAuthorizer

# No health-check probe is issued; the type is used directly.
authorizer = AccessTokenAuthorizer(
"AgJ1slfZsEng9bKsssB-tic0Kh8I...",
"https://platform.delinea.app",
server_type="platform",
)
```

An explicit `server_type` applies only to the instance that supplies it and is never written to the shared cache, so it cannot affect auto-detection for other authorizers. If a `base_url` is ever re-provisioned to a different server type while a long-lived process is running, call `Authorizer.clear_server_type_cache()` to force re-detection.

## Secret Server Cloud

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.
Expand Down Expand Up @@ -188,7 +207,7 @@ When using a self-signed certificate for SSL, the `REQUESTS_CA_BUNDLE` environme

## Create a Build Environment (optional)

The SDK requires [Python 3.8](https://www.python.org/downloads/) or higher.
The SDK requires [Python 3.10](https://www.python.org/downloads/) or higher.

First, ensure Python is in `$PATH`, then run:

Expand All @@ -201,9 +220,9 @@ cd python-tss-sdk
python -m venv venv
. venv/bin/activate

# Install dependencies
# Install dependencies (runtime + test/build tooling)
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
```

Valid credentials are required to run the unit tests. The credentials should be stored in environment variables or in a `.env` file:
Expand Down
28 changes: 28 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Security Policy

## Supported Versions

Security fixes are released against the latest published version of `python-tss-sdk` on PyPI. We do not backport fixes to older minor/major versions; please upgrade to the latest release to receive security patches.

## Reporting a Vulnerability

If you believe you have found a security vulnerability in this SDK, please report it responsibly through Delinea's coordinated disclosure program rather than opening a public GitHub issue:

- **Trust Portal (preferred):** <https://trust.delinea.com/>
- **Email:** <security@delinea.com>

Please include:

- A description of the vulnerability and its potential impact.
- Steps to reproduce, including a minimal code sample against this SDK if applicable.
- The SDK version (`delinea.__version__`) and Python version in use.

Do not include real credentials, tokens, or secret values from a live Secret Server/Platform tenant in a report.

## What to Expect

Delinea's security team acknowledges and triages reports submitted through the channels above; response times and disclosure timelines are governed by the program terms published at <https://trust.delinea.com/>. Please do not disclose a suspected vulnerability publicly until it has been addressed.

## Scope

This policy covers the SDK code in this repository (`delinea/secrets/server.py` and related packaging). Vulnerabilities in Secret Server, Delinea Platform, or other Delinea products should be reported through the same channels above, which will route them to the appropriate team.
Loading
Loading