Skip to content

Repository files navigation

This software is experimental and upcoming changes will break existing implementations. See Upcoming Changes for more details.

TEE Attestation Service (TAS)

A simple and secure service for Trusted Execution Environment (TEE) attestation, including key distribution, customisable policies and logging.

Table of Contents

Overview

TAS is a simple attestation service that verifies attestation evidence generated by TEEs. The standard deployment for TAS is as a service, to validate incoming evidence from booting confidential virtual machines (CVM), and after successful validation to provide a key to unlock the root file system of the CVM. This same process can be applied to unlocking anything, from access to data stores to identities on encrypted networks. You can also simply use the service to take in, verify, and log CVM attestation evidence at any point in the virtual machine's lifecycle.

TAS provides:

  • TEE Attestation: Validates AMD SEV-SNP and Intel TDX attestation evidence
  • GPU Attestation: Optional NVIDIA GPU attestation (via NRAS) cryptographically bound to the CPU TEE
  • Key Management: Secure key retrieval with cryptographic nonce validation
  • Policy Management: Store and validate security policies for attestation
  • Pluggable Architecture: Support for multiple Key Broker Modules (KBM)
  • Rate Limiting: Per-IP rate limiting on client routes with configurable limits and proxy-aware keying

Simplified TAS Architecture

Quick Start

To get the TAS server running in 5 minutes we recommend using a python virtual environment:

# 1. Clone and setup
git clone https://github.com/TEE-Attestation/TAS
cd tas
python -m venv venv
source venv/bin/activate

# 2. Install dependencies
git clone https://github.com/TEE-Attestation/sev_pytools.git
cd sev_pytools
pip install .
cd ..
git clone https://github.com/TEE-Attestation/tdx_pytools.git
cd tdx_pytools
pip install .
cd ..
# Optional: install nvidia_pytools for NVIDIA GPU attestation
git clone https://github.com/TEE-Attestation/nvidia_pytools.git
cd nvidia_pytools
pip install .
cd ..
pip install -r requirements.txt

# 3. Start Redis 6.2+ (required)
redis-server &

# 4. Set environment variables
export TAS_API_KEY="your-64-character-api-key-here-make-it-secure-and-long-enough"
export TAS_MANAGEMENT_API_KEY="your-64-character-management-key-here-different-from-api-key"
export TAS_KBM_PLUGIN="tas_kbm_mock"  # Use mock plugin for testing

# 5. Create and sign TAS policy
cd certs/policy/
# Using demo signer with auto-generated keys. To generate your own keys, refer https://github.com/TEE-Attestation/tas/blob/main/docs/POLICY.md
python3 demo_signer.py ./example_policy.json
# Add signature to your policy
jq -s '.[0] * .[1]' example_policy.json example_policy.json.sig > example_policy_signed.json
cd ../..

# 6. Run TAS
python app.py

TAS will be available at http://localhost:5000. See API Documentation for available endpoints.

With TAS running you can use the TAS agent to collect evidence and attest your CVMs. Alternatively for testing, check the API specification if you want to manually submit evidence to TAS.

Quick Run Script

scripts/quickrun.sh is a self-contained helper for spinning up a local TAS instance for development and testing. It handles the Python virtual environment, dependency installation, API key generation, and optional TLS — no external key manager or policy signing infrastructure required. It uses the mock KBM plugin backed by a local SQLite database.

Prerequisites

  • Python 3.10+
  • openssl
  • Redis running on localhost:6379

1. Build

Note: build should be run as a regular user — sudo is not required or recommended. If you do run build with sudo, all generated files will be owned by root, and you will also need to use sudo for subsequent run and uninstall commands.

Run once to set up the virtual environment, install dependencies, and generate API keys and config:

cd scripts
bash ./quickrun.sh build

Common build options:

# Behind a corporate proxy
bash ./quickrun.sh build --proxy "http://proxy.example.com:8080"

# Enable HTTPS (generates a self-signed certificate)
bash ./quickrun.sh build --tls

# Bind to a specific host/port (defaults: 127.0.0.1:5000)
bash ./quickrun.sh build --host 0.0.0.0 --port 5000

# Also install nvidia_pytools for GPU attestation
bash ./quickrun.sh build --include-nvidia

# Wipe and recreate the virtual environment

Note: NVIDIA GPU attestation is an optional feature in TAS. --include-nvidia installs nvidia_pytools into the virtual environment to enable it. This requires the nvidia_pytools source to be available (either cloned alongside this repo or accessible via pip). If you do not need GPU attestation, omit this flag — it is not required for AMD SEV-SNP or Intel TDX attestation. See Platform Support for more details.

# Wipe and recreate the virtual environment
bash ./quickrun.sh build --build-env

2. Add Secrets to the Mock KBM

Before policies can return secrets, inject the secret material for each key-id into the mock KBM's SQLite database:

# Inline value (visible in process list — fine for local testing)
python3 kbm_mock_secret_writer.py \
  --db .quickrun/kbm_db/kbm_mock_secrets.db \
  --key-id "my-policy-key" \
  --secret "my-secret-value"

# From stdin (keeps value out of shell history)
printf 'my-secret-value' | python3 kbm_mock_secret_writer.py \
  --db .quickrun/kbm_db/kbm_mock_secrets.db \
  --key-id "my-policy-key" \
  --secret -

The key-id must match the key_id field in the policy you create in the next step. Secrets are create-only — to remove one, use sqlite3 directly:

sqlite3 .quickrun/kbm_db/kbm_mock_secrets.db \
  "DELETE FROM secrets WHERE key_id='my-policy-key';"

3. Create a Policy

Use the tas-policy CLI to create and upload an attestation policy. The --key-id must match the secret you injected above:

# SEV (unsigned, for local testing)
./tas-policy create \
  --policy-id "my-policy" \
  --key-id "my-policy-key" \
  --cvm-type SEV \
  --name "My Test Policy" \
  --processor-family milan \
  --unsigned \
  --tas-host 127.0.0.1 --tas-port 5000 \
  --api-key-file /path/to/scripts/.quickrun/TAS_MANAGEMENT_API_KEY.txt \
  --no-tls

# TDX (unsigned, for local testing)
./tas-policy create \
  --policy-id "my-policy" \
  --key-id "my-policy-key" \
  --cvm-type TDX \
  --name "My Test Policy" \
  --unsigned \
  --tas-host 127.0.0.1 --tas-port 5000 \
  --api-key-file /path/to/scripts/.quickrun/TAS_MANAGEMENT_API_KEY.txt \
  --no-tls

To update an existing policy field (e.g. relax a minimum SVN requirement):

./tas-policy update \
  --policy-id "my-policy" \
  --unsigned \
  --min-tee-svn 0 \
  --tas-host 127.0.0.1 --tas-port 5000 \
  --api-key-file /path/to/scripts/.quickrun/TAS_MANAGEMENT_API_KEY.txt \
  --no-tls

SEV TCB note: --min-tee-svn sets the minimum requirement for current_tcb.tee, committed_tcb.tee, and launch_tcb.tee simultaneously. If attestation fails with current_tcb.tee value N < required minimum M, the VM's actual TEE SVN is N — lower the policy minimum to match.

4. Run

bash ./quickrun.sh run

The startup banner prints the server URL, truncated API keys, and example curl commands. Common run options:

# Override host/port at runtime
bash ./quickrun.sh run --host 0.0.0.0 --port 5000

# Start with TLS (build must have been run with --tls)
bash ./quickrun.sh run --tls

# Install and start as a persistent systemd service (requires sudo)
sudo bash ./quickrun.sh run --run-as-service

--run-as-service installs TAS as a systemd unit (tas-quickrun.service) and starts it immediately. Because creating a file under /etc/systemd/system/ requires elevated privileges, sudo is required. Once installed, the service starts automatically on boot and can be managed with standard systemctl commands:

# Check service status
sudo systemctl status tas-quickrun.service

# Stop the service
sudo systemctl stop tas-quickrun.service

# Start the service
sudo systemctl start tas-quickrun.service

# Restart the service
sudo systemctl restart tas-quickrun.service

# View logs
sudo journalctl -u tas-quickrun.service -f

To permanently remove the service, use the uninstall command (see Uninstall below).

5. Verify

curl -k -H "X-API-KEY: $(cat scripts/.quickrun/TAS_API_KEY.txt)" \
  http://127.0.0.1:5000/version

curl -k -H "X-MANAGEMENT-API-KEY: $(cat scripts/.quickrun/TAS_MANAGEMENT_API_KEY.txt)" \
  http://127.0.0.1:5000/management/policy/v0/list

6. Uninstall

Removes the virtual environment, generated config, API keys, and certificates. If a systemd service was installed, also stops and removes it:

# Foreground run only
bash ./quickrun.sh uninstall

# Including systemd service
sudo bash ./quickrun.sh uninstall

Prerequisites

Required Software

  • Python (>= 3.10)
  • Redis (>= 6.2)

Note: If you want to use the KMIP KBM plugin, ensure PyKMIP is installed. Note that PyKMIP does not work on Python 3.12 or later because it relies on ssl.wrap_socket(), which was removed in Python 3.12, so your venv will need a Python version between 3.8 and 3.11.

Verify Prerequisites

# Check Python installation
python --version
# For KMIP should show: Python 3.8.x - 3.11.x

# Check Redis connectivity
redis-cli ping
# Should respond: PONG

Platform Support

  • AMD SEV-SNP: Full attestation support
  • Intel TDX: Full attestation support
  • NVIDIA GPU: Optional GPU attestation via the NVIDIA Remote Attestation Service (NRAS), bound to AMD SEV-SNP / Intel TDX evidence (requires nvidia_pytools)

Installation

1. Environment Setup

# Clone repository
git clone https://github.com/TEE-Attestation/TAS
cd tas

# Create Python virtual environment
python -m venv venv
source venv/bin/activate

2. Install Dependencies

# Install TAS dependencies
pip install -r requirements.txt

# Install sev_pytools (required for AMD SEV-SNP support)
git clone https://github.com/TEE-Attestation/sev_pytools.git
cd sev_pytools
pip install .
cd ..

# Install tdx_pytools (required for Intel TDX support)
git clone https://github.com/TEE-Attestation/tdx_pytools.git
cd tdx_pytools
pip install .
cd ..

# Install nvidia_pytools (optional, required only for NVIDIA GPU attestation)
git clone https://github.com/TEE-Attestation/nvidia_pytools.git
cd nvidia_pytools
pip install .
cd ..

3. Configuration Setup

Option A: Quick Setup (Mock KBM)

export TAS_API_KEY="$(openssl rand -hex 32)"  # Generate secure client API key
export TAS_MANAGEMENT_API_KEY="$(openssl rand -hex 32)"  # Generate secure management API key
export TAS_KBM_PLUGIN="tas_kbm_mock"
echo "secrets:\n  test-key-1: test-secret-value" > config/mock_secrets.yaml
export TAS_KBM_CONFIG_FILE="config/mock_secrets.yaml"

Option B: Production Setup (KMIP JSON KBM)

export TAS_API_KEY="$(openssl rand -hex 32)"  # Generate secure client API key
export TAS_MANAGEMENT_API_KEY="$(openssl rand -hex 32)"  # Generate secure management API key
export TAS_KBM_PLUGIN="tas_kbm_kmip_json"
export TAS_KBM_CONFIG_FILE="./config/kmipjson/kmip.conf"

# Configure KMIP credentials in config/kmipjson/kmip.conf
# See docs/CONFIG.md for detailed configuration options

4. Running TAS

Option A: Run the TAS REST Server via HTTP

Use the flask run command, e.g.:

(venv) ~/tas$ flask run -h X.X.X.X -p 5000
TAS-KBM: Successfully connected to the KMIP server.
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://X.X.X.X:5000
Press CTRL+C to quit

Option B: Run the TAS REST Server via HTTPS

Use the flask run command, e.g.:

(venv) ~/tas$ flask run -h X.X.X.X -p 5000 --cert=path/to/cert.pem --key=config/tas_server.key
TAS-KBM: Successfully connected to the KMIP server.
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on https://X.X.X.X:5000
Press CTRL+C to quit

Option C: Run the TAS REST Server via gunicorn

(venv) ~/tas$ gunicorn -w 4 -b X.X.X.X:5000 app:app
[2025-05-13 05:12:43 -0600] [3085265] [INFO] Starting gunicorn 23.0.0
[2025-05-13 05:12:43 -0600] [3085265] [INFO] Listening at: http://X.X.X.X:5000
[2025-05-13 05:12:43 -0600] [3085265] [INFO] Using worker: sync
[2025-05-13 05:12:43 -0600] [3085268] [INFO] Booting worker with pid: 3085268
[2025-05-13 05:12:44 -0600] [3085269] [INFO] Booting worker with pid: 3085269
[2025-05-13 05:12:44 -0600] [3085270] [INFO] Booting worker with pid: 3085270
[2025-05-13 05:12:44 -0600] [3085271] [INFO] Booting worker with pid: 3085271
TAS: Successful Connection to Redis Server
TAS-KBM: Successfully connected to the KMIP server.
TAS: Successful Connection to Redis Server
TAS-KBM: Successfully connected to the KMIP server.
TAS: Successful Connection to Redis Server
TAS: Successful Connection to Redis Server
TAS-KBM: Successfully connected to the KMIP server.
TAS-KBM: Successfully connected to the KMIP server.

Option D: Run the TAS REST Server via HTTPS in a production mode

This mode requires the use of Nginx as a reverse-proxy, to sit in front of the TEE Attestation Service.

  1. Install Nginx

  2. Setup the SSL/TLS Certificates Place the private key and certificate in a secure directory, (e.g., /etc/nginx/ssl/).

    (venv) ~/tas$ sudo mkdir /etc/nginx/ssl
    (venv) ~/tas$ sudo cp config/tas_server.key /etc/nginx/ssl
    (venv) ~/tas$ sudo cp config/cert.pem /etc/nginx/ssl
    (venv) ~/tas$ sudo systemctl reload nginx
  3. Configure the required instance(s) of TAS. Create or edit the Nginx configuration file (e.g., /etc/nginx/sites-available/tas):

    server {
        listen 6000 ssl;
        server_name X.X.X.X;
    
        # SSL/TLS configuration: Thales CTM
        ssl_certificate /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/tas_server.key;
    
        # Proxy settings
        location /tas_customer1/ {
                proxy_pass http://127.0.0.1:5000/;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    
    }
  4. Reload Nginx

     (venv) ~/tas$ sudo systemctl reload nginx
  5. Run the TAS REST Server on the required localhost port

    (venv) ~/tas$ gunicorn -w 4 -b localhost:5000 app:app
    [2025-05-13 06:25:30 -0600] [3146615] [INFO] Starting gunicorn 23.0.0
    [2025-05-13 06:25:30 -0600] [3146615] [INFO] Listening at: http://127.0.0.1:5000 (3146615)
    [2025-05-13 06:25:30 -0600] [3146615] [INFO] Using worker: sync
    [2025-05-13 06:25:30 -0600] [3146618] [INFO] Booting worker with pid: 3146618
    [2025-05-13 06:25:30 -0600] [3146619] [INFO] Booting worker with pid: 3146619
    [2025-05-13 06:25:30 -0600] [3146620] [INFO] Booting worker with pid: 3146620
    [2025-05-13 06:25:30 -0600] [3146621] [INFO] Booting worker with pid: 3146621
    TAS: Successful Connection to Redis Server
    TAS: Successful Connection to Redis Server
    TAS-KBM: Successfully connected to the KMIP server.
    TAS-KBM: Successfully connected to the KMIP server.
    TAS: Successful Connection to Redis Server
    TAS-KBM: Successfully connected to the KMIP server.
    TAS: Successful Connection to Redis Server
    TAS-KBM: Successfully connected to the KMIP server.
  6. Ensure the TAS KBM Client application uses the correct URI. For above example: TAS_SERVER_URI=https://X.X.X.X:6000/tas_customer1

Configuration

TAS uses a flexible configuration system supporting environment variables and YAML/JSON files.

Required Environment Variables

# Minimum required configuration
export TAS_API_KEY="your-secure-64-character-minimum-api-key-here"
export TAS_MANAGEMENT_API_KEY="your-secure-64-character-minimum-management-key"
export TAS_KBM_PLUGIN="tas_kbm_mock"  # or "tas_kbm_kmip_json"

Complete Configuration Example

# Core settings
export TAS_API_KEY="your-production-api-key-must-be-64-characters-minimum"
export TAS_MANAGEMENT_API_KEY="your-management-api-key-must-be-64-characters-min"
export TAS_KBM_PLUGIN="tas_kbm_kmip_json"
export TAS_KBM_CONFIG_FILE="./config/kmipjson/kmip.conf"

# Optional settings
export TAS_REDIS_HOST="localhost"
export TAS_REDIS_PORT="6379"
export TAS_NONCE_EXPIRATION_SECONDS="300"
export TAS_PLUGIN_PREFIX="tas_kbm"
export TAS_EXTRA_PLUGIN_DIR="/opt/tas/plugins"

# Logging configuration
export TAS_OVERRIDE__logging__level="INFO"
export TAS_OVERRIDE__logging__file="/var/log/tas.log"

Detailed Configuration: See docs/CONFIG.md for complete configuration options, file formats, and environment variable precedence.

When TAS is Running

Service Verification

# Check TAS is running
curl -H "X-API-KEY: your-api-key" http://localhost:5000/version

# Expected response:
# {"version": "0.1.0"}

API Documentation

Core Endpoints

Endpoint Method Auth Header Description
/kb/v0/get_nonce GET X-API-KEY Generate attestation nonce
/kb/v0/get_secret POST X-API-KEY Retrieve secret after TEE verification
/version GET X-API-KEY Get TAS version

Management Endpoints

Endpoint Method Auth Header Description
/management/policy/v0/store POST X-MANAGEMENT-API-KEY Store security policy
/management/policy/v0/get/<key> GET X-MANAGEMENT-API-KEY Retrieve security policy
/management/policy/v0/list GET X-MANAGEMENT-API-KEY List all policies
/management/policy/v0/delete/<key> DELETE X-MANAGEMENT-API-KEY Delete security policy

Deprecated Endpoints

Deprecated: The /policy/v0/* endpoints below are deprecated and will be removed after 31 March 2026. Use the /management/policy/v0/* endpoints above instead. Deprecated responses include Deprecation, Sunset, and Warning headers per RFC 8594.

Endpoint Method Auth Header Description
/policy/v0/store POST X-MANAGEMENT-API-KEY Store security policy (use /management/policy/v0/store)
/policy/v0/get/<key> GET X-MANAGEMENT-API-KEY Retrieve security policy (use /management/policy/v0/get/<key>)
/policy/v0/list GET X-MANAGEMENT-API-KEY List all policies (use /management/policy/v0/list)
/policy/v0/delete/<key> DELETE X-MANAGEMENT-API-KEY Delete security policy (use /management/policy/v0/delete/<key>)

Authentication

TAS uses separate API keys for client and management operations:

# Client endpoints (attestation, key retrieval)
curl -H "X-API-KEY: your-api-key" <endpoint>

# Management endpoints (policy CRUD)
curl -H "X-MANAGEMENT-API-KEY: your-management-key" <endpoint>

Example API Usage

1. Get Nonce

curl -H "X-API-KEY: your-api-key" \
  http://localhost:5000/kb/v0/get_nonce

2. Request Secret

curl -X POST \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: your-api-key" \
  -d '{
    "tee-type": "amd-sev-snp",
    "nonce": "obtained-from-get-nonce",
    "tee-evidence": "base64-encoded-attestation-report",
    "policy-id": "my-policy-001",
    "report-data-binding": true,
    "wrapping-key": "base64-encoded-public-key"
  }' \
  http://localhost:5000/kb/v0/get_secret

3. Store Policy

curl -X POST \
  -H "Content-Type: application/json" \
  -H "X-MANAGEMENT-API-KEY: your-management-key" \
  -d '{
    "metadata": {
      "name": "Test Policy",
      "version": "1.0",
      "policy_type": "...",
      "policy_id": "my-policy-001",
      "key_id": "my-key-1"
    },
    "signature": {...},
    "validation_rules": {
      "measurement": {"exact_match": "abc123"},
      "debug": false
    }
  }' \
  http://localhost:5000/management/policy/v0/store

Complete API Documentation: See docs/openapi.yaml and docs/openapi.json files

Detailed Configuration: See docs/POLICY.md for documentation on policy structure, signing, and uploading.

Redis Key Policies

Before a confidential guest VM can be attested using tas_agent one or more key access policies must be loaded into redis. Detailed usage of redis for data management is beyond the scope of this document. To get started, however, the redis-cli tool can be used to issue the set command for a given policy key/value pair.

The redis keys used by TAS take the format policy:$POLICY_ID, where $POLICY_ID is the unique identifier specified in the policy's metadata.policy_id field. The named key_id within the policy metadata must also be present in the configured key broker module.

For example, to allow a TDX confidential guest to attest and request a key using a policy with ID my-tdx-policy-001, the redis policy key record would be identified by policy:my-tdx-policy-001. The value to be stored against the policy key is the JSON document that represents the (signed) attestation policy. A complete example would be

# redis-cli
127.0.0.1:6379> set policy:my-tdx-policy-001 '{"metadata":{"name":..snip......"cpu_svn":{"exact_match":"030...000"}}}}}}'

KBM Plugins

TAS supports pluggable Key Broker Modules (KBM) for different backend key management systems.

Available Plugins

Plugin Description Use Case
tas_kbm_kmip_json KMIP JSON protocol backend Production with KMIP servers (Cosmain KMS, etc.)
tas_kbm_thales_ctm Thales CipherTrust Manager backend Production with Thales CTM for key wrapping and export
tas_kbm_mock Software-based mock Development and testing

Plugin Interface

Each KBM plugin must implement three functions:

def kbm_open_client_connection(config_file: str = None):
    """Initialize and return a client handle

    Args:
        config_file: Path to plugin configuration file (YAML or JSON)

    Returns:
        Client handle for use with kbm_get_secret
    """

def kbm_get_secret(client, key_id: str, wrapping_key: bytes):
    """Retrieve and return a secret (JSON-serializable)

    Args:
        client: Client handle from kbm_open_client_connection
        key_id: Identifier for the secret to retrieve
        wrapping_key: Client RSA public key for wrapping the secret

    Returns:
        Dictionary with keys: wrapped_key, blob, iv, tag (all base64-encoded)
    """

def kbm_close_client_connection(client) -> None:
    """Cleanup client connection

    Args:
        client: Client handle to close
    """

Host-Provided Dependencies (Optional)

Plugins can opt-in to receive host-provided dependencies via a module-level declaration:

# Module-level declaration: what kwargs this plugin wants from the host
KBM_HOST_KWARGS = {"redis_client"}  # or set() if no dependencies needed

Currently supported host kwargs:

  • redis_client: Redis connection for distributed locking, caching, or other backend needs

The host will only pass declared dependencies to kbm_open_client_connection(). Plugins that don't declare dependencies can omit those parameters from their function signature.

Example: If your plugin doesn't need Redis, simply don't declare it:

# tas_kbm_minimal.py
KBM_HOST_KWARGS = set()

def kbm_open_client_connection(config_file: str = None):
    # No redis_client parameter needed
    ...

If your plugin needs Redis for distributed locking:

# tas_kbm_with_redis.py
KBM_HOST_KWARGS = {"redis_client"}

def kbm_open_client_connection(config_file: str = None, redis_client=None):
    # redis_client will be provided by the host
    ...

Plugin Configuration

KMIP JSON Plugin

export TAS_KBM_PLUGIN="tas_kbm_kmip_json"
export TAS_KBM_CONFIG_FILE="./config/kmipjson/kmip.conf"

The KMIP configuration file should contain KMIP server details and credentials.

Thales CTM REST Plugin

export TAS_KBM_PLUGIN="tas_kbm_thales_ctm"
export TAS_KBM_CONFIG_FILE="./config/thales_ctm/thales_ctm.yaml"

The Thales CTM REST Plugin configuration file should contain CTM server details and credentials, see documentation on how to configure it.

Mock Plugin

export TAS_KBM_PLUGIN="tas_kbm_mock"
export TAS_KBM_CONFIG_FILE="./config/mock_secrets.yaml"

Example mock configuration file:

secrets:
  test-key-1: "test-secret-value"
  another-key: "another-secret"

See here on how to configure the Mock KBM.

Creating Custom Plugins

  1. Create a Python module in plugins/ directory
  2. Module name must start with TAS_PLUGIN_PREFIX (default: tas_kbm)
  3. Implement the three required functions
  4. Optionally declare host-provided dependencies via KBM_HOST_KWARGS (module-level set)
  5. Set TAS_KBM_PLUGIN to your module name

Example custom plugin without host dependencies:

# plugins/tas_kbm_custom.py

# Declare that this plugin does not need any host-provided kwargs
KBM_HOST_KWARGS = set()

def kbm_open_client_connection(config_file: str = None):
    # Initialize your backend client
    return my_backend_client

def kbm_get_secret(client, key_id: str, wrapping_key: bytes):
    # Retrieve secret from your backend
    # Wrap with provided public key
    return wrapped_secret

def kbm_close_client_connection(client) -> None:
    # Cleanup
    client.disconnect()

__all__ = [
    "kbm_open_client_connection",
    "kbm_get_secret",
    "kbm_close_client_connection"
]

Example custom plugin with Redis dependency:

# plugins/tas_kbm_custom_with_redis.py

from typing import Optional, Any

# Declare that this plugin wants redis_client from the host
KBM_HOST_KWARGS = {"redis_client"}

def kbm_open_client_connection(config_file: str = None, redis_client: Optional[Any] = None):
    # Initialize your backend client
    # Use redis_client for distributed locking, caching, etc.
    return my_backend_client

def kbm_get_secret(client, key_id: str, wrapping_key: bytes):
    # Retrieve secret from your backend
    # Wrap with provided public key
    return wrapped_secret

def kbm_close_client_connection(client) -> None:
    # Cleanup
    client.disconnect()

__all__ = [
    "kbm_open_client_connection",
    "kbm_get_secret",
    "kbm_close_client_connection"
]

Plugin Discovery

  • Default search path: ./plugins/
  • Additional search path: Set TAS_EXTRA_PLUGIN_DIR
  • Plugin selection: Set TAS_KBM_PLUGIN to module name

Development

Running Tests

# Run all tests
python -m pytest tests/ -v

# Run specific test file
python -m pytest tests/test_policy_helper.py -v

# Run with coverage
python -m pytest tests/ --cov=tas --cov-report=html

Upcoming Changes

  • Policy identifier changes
  • Removal of deprecated /policy/v0/* endpoints (31 March 2026) — migrate to /management/policy/v0/*

Contributing

Contributing to the project is simple! Just send a pull request through GitHub. For detailed instructions on formatting your changes and following our contribution guidelines, take a look at the CONTRIBUTING file.

Troubleshooting

Redis Connection Failed

Error: Failed to connect to the Redis server

Solution: Ensure Redis 6.2+ is running on the configured host/port

redis-server &  # Start Redis
redis-cli ping  # Test connectivity

API Key Error

Error: TAS_API_KEY environment variable is not set

Solution: Set secure API keys (minimum 64 characters each)

export TAS_API_KEY="$(openssl rand -hex 32)"
export TAS_MANAGEMENT_API_KEY="$(openssl rand -hex 32)"

KBM Connection Issues

Error: Failed to initialize KBM client

Solutions:

  • Check that the KBM configuration file exists and is valid
  • Verify KMS server connectivity
  • Use mock plugin for testing: export TAS_KBM_PLUGIN=tas_kbm_mock

Python Version Compatibility

Tested on Python 3.10 - 3.14.

Debug Mode

Enable detailed logging:

export TAS_OVERRIDE__logging__level="DEBUG"
python app.py

Health Checks

# Basic connectivity
curl -H "X-API-KEY: your-key" http://localhost:5000/version

# Redis connectivity
redis-cli ping

# Check TAS logs
tail -f tas.log

Getting Help

  • Issues: Open an issue on the repository

License

This project is licensed under the MIT license. See LICENSE file for details.

About

Server that verifies TEE attestations, manages policies and orchestrates secret distribution.

Topics

Resources

Contributing

Security policy

Stars

4 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages