Skip to content
Back to skills

3054 Mtls 54eac01a

ASecurity

This guide covers how to set up mutual TLS (mTLS) authentication between ContextForge and external plugin servers.

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 1, 2026
devopspythonrustgobashdockerkubernetestestingsecurity

Works with

  • cli
  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 3054-mtls_54eac01a --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 3054 Mtls 54eac01a?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 3054 Mtls 54eac01a
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-3054-mtls-54eac01a/badge)](https://www.skillsdirectory.com/skills/tools-only-3054-mtls-54eac01a)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# External Plugin mTLS Setup Guide

This guide covers how to set up mutual TLS (mTLS) authentication between ContextForge and external plugin servers.

## Port Configuration

**Standard port convention:**

- **Port 8000**: Main plugin service (HTTP or HTTPS/mTLS)
- **Port 9000**: Health check endpoint (automatically starts on port+1000 when mTLS is enabled)

When mTLS is enabled, the plugin runtime automatically starts a separate HTTP-only health check server on port 9000 (configurable via `port + 1000` formula). This allows health checks without requiring mTLS client certificates.

## Certificate Generation

ContextForge includes Makefile targets to manage the complete certificate infrastructure for plugin mTLS.

### Quick Start

```bash
# Generate complete mTLS infrastructure (recommended)
make certs-mcp-all

# This automatically:
# 1. Creates a Certificate Authority (CA)
# 2. Generates gateway client certificate
# 3. Reads plugins/external/config.yaml and generates server certificates for all external plugins
```

**Certificate validity**: Default is **825 days** (~2.25 years)

**Output structure**:
```
certs/mcp/
├── ca/                           # Certificate Authority
│   ├── ca.key                   # CA private key (protect!)
│   └── ca.crt                   # CA certificate
├── gateway/                      # Gateway client certificates
│   ├── client.key               # Client private key
│   ├── client.crt               # Client certificate
│   └── ca.crt                   # Copy of CA cert
└── plugins/                      # Plugin server certificates
    └── PluginName/
        ├── server.key           # Server private key
        ├── server.crt           # Server certificate
        └── ca.crt               # Copy of CA cert
```

### Makefile Targets

#### `make certs-mcp-all`

Generate complete mTLS infrastructure. This is the **recommended** command for setting up mTLS.

**What it does**:

1. Calls `certs-mcp-ca` to create the CA (if not exists)
2. Calls `certs-mcp-gateway` to create gateway client certificate (if not exists)
3. Reads `plugins/external/config.yaml` and generates certificates for all plugins with `kind: external`

**Usage**:
```bash
# Use default config file (plugins/external/config.yaml)
make certs-mcp-all

# Use custom config file
make certs-mcp-all MCP_PLUGIN_CONFIG=path/to/custom-config.yaml

# Custom certificate validity (in days)
make certs-mcp-all MCP_CERT_DAYS=365

# Combine both options
make certs-mcp-all MCP_PLUGIN_CONFIG=config.yaml MCP_CERT_DAYS=730
```

**Config file format** (`plugins/external/config.yaml`):
```yaml
plugins:
  - name: "MyPlugin"           # Certificate will be created for this plugin
    kind: "external"           # Must be "external"
    mcp:
      proto: STREAMABLEHTTP
      url: http://127.0.0.1:8000/mcp

  - name: "AnotherPlugin"
    kind: "external"
    mcp:
      proto: STREAMABLEHTTP
      url: http://127.0.0.1:8001/mcp
```

**Fallback behavior**: If the config file doesn't exist or PyYAML is not installed, example certificates are generated for `example-plugin-a` and `example-plugin-b`.

#### `make certs-mcp-ca`

Generate the Certificate Authority (CA) for plugin mTLS. This is typically called automatically by other targets.

**What it does**:

- Creates `certs/mcp/ca/ca.key` (4096-bit RSA private key)
- Creates `certs/mcp/ca/ca.crt` (CA certificate)
- Sets file permissions: `600` for `.key`, `644` for `.crt`

**Usage**:
```bash
# Generate CA (one-time setup)
make certs-mcp-ca

# Custom validity
make certs-mcp-ca MCP_CERT_DAYS=1825
```

**Safety**: Won't overwrite existing CA. To regenerate, delete `certs/mcp/ca/` first.

**⚠️  Warning**: The CA private key (`ca.key`) is critical. Protect it carefully!

#### `make certs-mcp-gateway`

Generate the gateway client certificate used by ContextForge to authenticate to plugin servers.

**What it does**:

- Depends on `certs-mcp-ca` (creates CA if needed)
- Creates `certs/mcp/gateway/client.key` (4096-bit RSA private key)
- Creates `certs/mcp/gateway/client.crt` (client certificate signed by CA)
- Copies `ca.crt` to `certs/mcp/gateway/`

**Usage**:
```bash
# Generate gateway client certificate
make certs-mcp-gateway

# Custom validity
make certs-mcp-gateway MCP_CERT_DAYS=365
```

**Safety**: Won't overwrite existing certificate.

#### `make certs-mcp-plugin`

Generate a server certificate for a specific plugin.

**What it does**:

- Depends on `certs-mcp-ca` (creates CA if needed)
- Creates `certs/mcp/plugins/<PLUGIN_NAME>/server.key`
- Creates `certs/mcp/plugins/<PLUGIN_NAME>/server.crt` with Subject Alternative Names (SANs):

  - `DNS:<PLUGIN_NAME>`
  - `DNS:mcp-plugin-<PLUGIN_NAME>`
  - `DNS:localhost`

- Copies `ca.crt` to plugin directory

**Usage**:
```bash
# Generate certificate for specific plugin
make certs-mcp-plugin PLUGIN_NAME=MyCustomPlugin

# Custom validity
make certs-mcp-plugin PLUGIN_NAME=MyPlugin MCP_CERT_DAYS=365
```

**Required**: `PLUGIN_NAME` parameter must be provided.

**Use case**: Add a new plugin after running `certs-mcp-all`, or generate certificates manually.

#### `make certs-mcp-check`

Check expiry dates of all MCP certificates.

**What it does**:

- Displays expiry dates for CA, gateway client, and all plugin certificates
- Shows remaining validity period

**Usage**:
```bash
make certs-mcp-check
```

**Output example**:
```
🔍  Checking MCP certificate expiry dates...

📋 CA Certificate:
   Expires: Jan 15 10:30:45 2027 GMT

📋 Gateway Client Certificate:
   Expires: Jan 15 10:31:22 2027 GMT

📋 Plugin Certificates:
   MyPlugin: Jan 15 10:32:10 2027 GMT
   AnotherPlugin: Jan 15 10:32:45 2027 GMT
```

### Certificate Properties

All certificates generated include:

- **Algorithm**: RSA with SHA-256
- **CA Key Size**: 4096 bits
- **Client/Server Key Size**: 4096 bits
- **Default Validity**: 825 days
- **Subject Alternative Names** (plugins): DNS entries for plugin name and localhost

### Important Notes

1. **All `ca.crt` files are identical** - They are copies of the root CA certificate distributed to each location for convenience
2. **Safety features** - Commands won't overwrite existing certificates. To regenerate, delete the target directory first
3. **File permissions** - Automatically set to secure values:

   - Private keys (`.key`): `600` (owner read/write only)
   - Certificates (`.crt`): `644` (world-readable)

4. **Configuration variables**:

   - `MCP_CERT_DAYS`: Certificate validity in days (default: 825)
   - `MCP_PLUGIN_CONFIG`: Path to plugin config file (default: `plugins/external/config.yaml`)

## Configuration Options

You can configure mTLS using either YAML files or environment variables.

### Option 1: YAML Configuration

#### Server Configuration (Plugin)

In your plugin config file (e.g., `plugins/test.yaml`):

```yaml
plugins:
  - name: "ReplaceBadWordsPlugin"
    kind: "plugins.regex_filter.search_replace.SearchReplacePlugin"
    # ... plugin config ...

server_settings:
  host: "127.0.0.1"
  port: 8000
  tls:
    certfile: certs/mcp/plugins/ReplaceBadWordsPlugin/server.crt
    keyfile: certs/mcp/plugins/ReplaceBadWordsPlugin/server.key
    ca_bundle: certs/mcp/plugins/ReplaceBadWordsPlugin/ca.crt
    ssl_cert_reqs: 2  # 2 = CERT_REQUIRED (enforce client certificates)
```

Start the server (for testing):
```bash
PYTHONPATH=. PLUGINS_CONFIG_PATH="plugins/test.yaml" \
  python3 mcpgateway/plugins/framework/external/mcp/server/runtime.py
```

#### Client Configuration (Gateway)

In your gateway plugin config file (e.g., `plugins/external/config-client.yaml`):

```yaml
plugins:
  - name: "ReplaceBadWordsPlugin"
    kind: "external"
    mcp:
      proto: STREAMABLEHTTP
      url: https://127.0.0.1:8000/mcp
      tls:
        certfile: certs/mcp/gateway/client.crt
        keyfile: certs/mcp/gateway/client.key
        ca_bundle: certs/mcp/gateway/ca.crt
        verify: true
        check_hostname: false
```

### Option 2: Environment Variables

#### Server Environment Variables

```bash
# Server configuration
export PLUGINS_SERVER_HOST="127.0.0.1"
export PLUGINS_SERVER_PORT="8000"
export PLUGINS_SERVER_SSL_ENABLED="true"

# TLS/mTLS configuration
export PLUGINS_SERVER_SSL_KEYFILE="certs/mcp/plugins/ReplaceBadWordsPlugin/server.key"
export PLUGINS_SERVER_SSL_CERTFILE="certs/mcp/plugins/ReplaceBadWordsPlugin/server.crt"
export PLUGINS_SERVER_SSL_CA_CERTS="certs/mcp/plugins/ReplaceBadWordsPlugin/ca.crt"
export PLUGINS_SERVER_SSL_CERT_REQS="2"  # 2 = CERT_REQUIRED
```

Start the server (YAML without `server_settings` section for testing):
```bash
PYTHONPATH=. PLUGINS_CONFIG_PATH="plugins/test.yaml" \
  python3 mcpgateway/plugins/framework/external/mcp/server/runtime.py
```

#### Client Environment Variables

```bash
export PLUGINS_CLIENT_MTLS_CERTFILE="certs/mcp/gateway/client.crt"
export PLUGINS_CLIENT_MTLS_KEYFILE="certs/mcp/gateway/client.key"
export PLUGINS_CLIENT_MTLS_CA_BUNDLE="certs/mcp/gateway/ca.crt"
export PLUGINS_CLIENT_MTLS_VERIFY="true"
export PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME="false"
```

Run your gateway code (YAML without `tls` section in `mcp` config).

## Environment Variable Reference

### Server Variables (Plugin)

| Variable | Description | Example |
|----------|-------------|---------|
| `PLUGINS_SERVER_HOST` | Server bind address | `127.0.0.1` |
| `PLUGINS_SERVER_PORT` | Server bind port | `8000` |
| `PLUGINS_SERVER_UDS` | Unix domain socket path (Streamable HTTP only; no TLS) | `/var/run/mcp-plugin.sock` |
| `PLUGINS_SERVER_SSL_ENABLED` | Enable SSL/TLS | `true` |
| `PLUGINS_SERVER_SSL_KEYFILE` | Path to server private key | `certs/.../server.key` |
| `PLUGINS_SERVER_SSL_CERTFILE` | Path to server certificate | `certs/.../server.crt` |
| `PLUGINS_SERVER_SSL_CA_CERTS` | Path to CA bundle | `certs/.../ca.crt` |
| `PLUGINS_SERVER_SSL_CERT_REQS` | Client cert requirement (0-2) | `2` |
| `PLUGINS_SERVER_SSL_KEYFILE_PASSWORD` | Password for encrypted key | `password` |

!!! note
    `PLUGINS_SERVER_UDS` and TLS are mutually exclusive. UDS runs without TLS by design.

**`ssl_cert_reqs` values:**

- `0` = `CERT_NONE` - No client certificate required
- `1` = `CERT_OPTIONAL` - Client certificate requested but not required
- `2` = `CERT_REQUIRED` - Client certificate required (mTLS)

### Client Variables (Gateway)

| Variable | Description | Example |
|----------|-------------|---------|
| `PLUGINS_CLIENT_MTLS_CERTFILE` | Path to client certificate | `certs/.../client.crt` |
| `PLUGINS_CLIENT_MTLS_KEYFILE` | Path to client private key | `certs/.../client.key` |
| `PLUGINS_CLIENT_MTLS_CA_BUNDLE` | Path to CA bundle | `certs/.../ca.crt` |
| `PLUGINS_CLIENT_MTLS_VERIFY` | Verify server certificate | `true` |
| `PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME` | Verify server hostname | `false` |
| `PLUGINS_CLIENT_MTLS_KEYFILE_PASSWORD` | Password for encrypted key | `password` |

## Testing mTLS

### Test without TLS

```bash
# Server
PYTHONPATH=. PLUGINS_CONFIG_PATH="plugins/test.yaml" \
  PLUGINS_SERVER_HOST="127.0.0.1" \
  PLUGINS_SERVER_PORT="8000" \
  PLUGINS_SERVER_SSL_ENABLED="false" \
  python3 mcpgateway/plugins/framework/external/mcp/server/runtime.py &

# Client config should use: url: http://127.0.0.1:8000/mcp
```

### Test with mTLS (YAML)

```bash
# Server (config has server_settings.tls section)
PYTHONPATH=. PLUGINS_CONFIG_PATH="plugins/test.mtls.yaml" \
  python3 mcpgateway/plugins/framework/external/mcp/server/runtime.py &

# Client (config has mcp.tls section)
python3 your_client.py
```

### Test with mTLS (Environment Variables)

```bash
# Server (config has no server_settings section)
# Note: When mTLS is enabled, a health check server automatically starts on port 9000 (port+1000)
PYTHONPATH=. \
  PLUGINS_CONFIG_PATH="plugins/test.yaml" \
  PLUGINS_SERVER_HOST="127.0.0.1" \
  PLUGINS_SERVER_PORT="8000" \
  PLUGINS_SERVER_SSL_ENABLED="true" \
  PLUGINS_SERVER_SSL_KEYFILE="certs/mcp/plugins/ReplaceBadWordsPlugin/server.key" \
  PLUGINS_SERVER_SSL_CERTFILE="certs/mcp/plugins/ReplaceBadWordsPlugin/server.crt" \
  PLUGINS_SERVER_SSL_CA_CERTS="certs/mcp/plugins/ReplaceBadWordsPlugin/ca.crt" \
  PLUGINS_SERVER_SSL_CERT_REQS="2" \
  python3 mcpgateway/plugins/framework/external/mcp/server/runtime.py &

# Client (config has no mcp.tls section)
PLUGINS_CLIENT_MTLS_CERTFILE="certs/mcp/gateway/client.crt" \
  PLUGINS_CLIENT_MTLS_KEYFILE="certs/mcp/gateway/client.key" \
  PLUGINS_CLIENT_MTLS_CA_BUNDLE="certs/mcp/gateway/ca.crt" \
  PLUGINS_CLIENT_MTLS_VERIFY="true" \
  PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME="false" \
  python3 your_client.py
```

## How mTLS Works

1. **Certificate Authority (CA)**: A single root CA (`ca.crt`) signs both client and server certificates
2. **Server Certificate**: Plugin server presents its certificate (`server.crt`) to clients
3. **Client Certificate**: Gateway presents its certificate (`client.crt`) to the plugin server
4. **Mutual Verification**: Both parties verify each other's certificates against the CA bundle
5. **Secure Channel**: After mutual authentication, all communication is encrypted

## Configuration Priority

Environment variables take precedence over YAML configuration:

- If `PLUGINS_SERVER_SSL_ENABLED=true`, env vars override `server_settings.tls`
- If client env vars are set, they override `mcp.tls` in YAML

## Hostname Verification (`check_hostname`)

### Overview
`check_hostname` is a **client-side only** setting that verifies the server's certificate matches the hostname/IP you're connecting to.

### How It Works
The client checks if the URL hostname matches entries in the server certificate's:

- **Common Name (CN)**: `CN=mcp-plugin-ReplaceBadWordsPlugin`
- **Subject Alternative Names (SANs)**: DNS names or IP addresses

### Checking Certificate SANs
```bash
# View DNS and IP SANs in server certificate
openssl x509 -in certs/mcp/plugins/ReplaceBadWordsPlugin/server.crt -text -noout | grep -A 5 "Subject Alternative Name"

# Example output:
# X509v3 Subject Alternative Name:
#     DNS:ReplaceBadWordsPlugin, DNS:mcp-plugin-ReplaceBadWordsPlugin, DNS:localhost
```

### Configuration Examples

#### Option 1: Use `localhost` with `check_hostname: true`
```yaml
# Client config
mcp:
  url: https://localhost:8000/mcp
  tls:
    check_hostname: true  # Works because "localhost" is in DNS SANs
```

Or with environment variables:
```bash
export PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME="true"
# Connect to: https://localhost:8000/mcp
```

#### Option 2: Use IP address with `check_hostname: false`
```yaml
# Client config
mcp:
  url: https://127.0.0.1:8000/mcp
  tls:
    check_hostname: false  # Required because 127.0.0.1 is not in SANs
```

Or with environment variables:
```bash
export PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME="false"
# Connect to: https://127.0.0.1:8000/mcp
```

#### Option 3: Add IP SANs to certificate (Advanced)
If you need `check_hostname: true` with IP addresses, regenerate certificates with IP SANs:

```bash
# Modify Makefile to add IP SANs when generating certificates
# Add to server.ext or openssl command:
# subjectAltName = DNS:localhost, DNS:plugin-name, IP:127.0.0.1, IP:0.0.0.0
```

### Server-Side Hostname Verification
There is **no** `check_hostname` setting on the server side. The server only:

1. Verifies the client certificate is signed by the trusted CA
2. Checks if `ssl_cert_reqs=2` (CERT_REQUIRED) to enforce client certificates

### Testing Hostname Verification

#### Test 1: Valid hostname (should succeed)
```bash
# Server bound to 0.0.0.0 (accepts all interfaces)
PLUGINS_SERVER_HOST="0.0.0.0" ...

# Client connecting to localhost with hostname check
export PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME="true"
# URL: https://localhost:8000/mcp
# Result: ✅ Success (localhost is in DNS SANs)
```

#### Test 2: IP address with hostname check (should fail)
```bash
# Client connecting to IP with hostname check
export PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME="true"
# URL: https://127.0.0.1:8000/mcp
# Result: ❌ Fails with "IP address mismatch, certificate is not valid for '127.0.0.1'"
```

## Troubleshooting

### Connection Refused
- Ensure server is running: `lsof -i :8000`
- Check server logs for startup errors
- Verify server is bound to correct interface (0.0.0.0 for all, 127.0.0.1 for localhost only)
- Note: When mTLS is enabled, a health check server also runs on port 9000 (port+1000)

### Certificate Verification Failed
- Verify CA bundle matches on both sides: `md5 certs/**/ca.crt`
- Check certificate paths are correct
- Ensure certificates haven't expired: `openssl x509 -in cert.crt -noout -dates`

### Hostname Verification Failed
Error: `certificate verify failed: IP address mismatch` or `Hostname mismatch`

**Solutions:**

1. **Use hostname from SANs**: Connect to `https://localhost:8000` instead of `https://127.0.0.1:8000`
2. **Disable hostname check**: Set `check_hostname: false` or `PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME="false"`
3. **Add IP to SANs**: Regenerate certificates with IP SANs included

## mTLS Deployment Hardening Guidelines

For production deployments, follow these security best practices to ensure robust mTLS configuration:

| Category | Recommendation | Configuration / Option | Notes |
| --- | --- | --- | --- |
| **Certificate Verification** | Keep hostname and certificate chain verification enabled. | **YAML**: `check_hostname: true` and valid `ca_bundle`<br>**Environment**: `PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME="true"` and valid `PLUGINS_CLIENT_MTLS_CA_BUNDLE` or `PLUGINS_SERVER_SSL_CA_CERTS` | Only disable in trusted, local test setups. |
| **CA Management** | Use a dedicated CA for gateway ↔ plugin certificates. | **YAML**: `ca_bundle: certs/mcp/gateway/ca.crt`<br>**Environment**: `PLUGINS_SERVER_SSL_CA_CERTS` or `PLUGINS_CLIENT_MTLS_CA_BUNDLE` | Ensures trust is limited to your deployment's CA. |
| **Certificate Rotation** | Regenerate and redeploy certificates periodically. | **Local/Docker**: Use Makefile targets: `make certs-mcp-all`, `make certs-mcp-check`<br>**Kubernetes**: Use [cert-manager](https://cert-manager.io/) for automated certificate lifecycle management | Recommended: short-lived certs (e.g. 90–180 days). Configure with `MCP_CERT_DAYS` variable for Makefile targets. |
| **Key Protection** | Limit read access to private key files. | **YAML**: `keyfile` paths (e.g., `server.key`, `client.key`)<br>**Environment**: `PLUGINS_SERVER_SSL_KEYFILE` or `PLUGINS_CLIENT_MTLS_KEYFILE`<br>**File permissions**: `600` (owner read/write only) | Keys should be owned and readable only by the service account. |
| **TLS Version Enforcement** | Enforce TLS 1.2 or newer. | Controlled by Python's `ssl` defaults or runtime settings. | No additional configuration required; defaults are secure. |
| **Health Endpoint Exposure** | Bind health endpoints to localhost only. | **YAML**: `server_settings.host: 127.0.0.1`<br>**Environment**: `PLUGINS_SERVER_HOST="127.0.0.1"` | Prevents unauthenticated HTTP access from external hosts. Health check server (port+1000) is HTTP-only. |
| **Logging & Diagnostics** | Enable debug logs for TLS handshake troubleshooting. | `LOG_LEVEL=DEBUG` or `--verbose` | Logs cert subjects and handshake results (safe to enable temporarily). |
| **Insecure Mode Control** | Disable insecure (non-TLS) connections in production. | **Environment**: `PLUGINS_SERVER_SSL_ENABLED="true"`<br>Set `ssl_cert_reqs: 2` (CERT_REQUIRED) for mTLS enforcement | Guarantees all plugin communications use mTLS. |
| **Configuration Validation** | Fail fast on missing or invalid TLS configuration. | Enabled automatically at startup. | Ensures system won't silently downgrade to HTTP. |

### Implementation Checklist

When deploying plugin mTLS in production:

1. **Generate Certificates**:

   - **Local/Docker**: Use `make certs-mcp-all` to create complete certificate infrastructure
   - **Kubernetes**: Deploy [cert-manager](https://cert-manager.io/) and configure Certificate resources for automated issuance and renewal

2. **Verify Expiration**:

   - **Local/Docker**: Run `make certs-mcp-check` regularly to monitor certificate validity
   - **Kubernetes**: cert-manager automatically monitors and renews certificates before expiration

3. **Secure Private Keys**: Ensure all `.key` files have `600` permissions and are owned by service accounts (or stored in Kubernetes Secrets with appropriate RBAC)
4. **Enable Hostname Verification**: Set `check_hostname: true` or `PLUGINS_CLIENT_MTLS_CHECK_HOSTNAME="true"` unless using IP addresses
5. **Configure Health Checks**: Bind health servers to `127.0.0.1` to prevent external access
6. **Enforce mTLS**: Set `PLUGINS_SERVER_SSL_CERT_REQS="2"` to require client certificates
7. **Monitor Logs**: Enable `LOG_LEVEL=DEBUG` temporarily during initial deployment to verify handshakes
8. **Plan Rotation**:

   - **Local/Docker**: Schedule certificate rotation every 90-180 days using `MCP_CERT_DAYS` parameter
   - **Kubernetes**: Configure cert-manager Certificate resources with appropriate `renewBefore` duration (typically 30 days before expiration)

### Security Validation

After deployment, verify your mTLS configuration:

```bash
# 1. Check certificate expiration dates
make certs-mcp-check

# 2. Verify file permissions on private keys
find certs/mcp -name "*.key" -exec ls -la {} \;

# 3. Test certificate verification
openssl verify -CAfile certs/mcp/ca/ca.crt certs/mcp/gateway/client.crt

# 4. Confirm TLS version enforcement
openssl s_client -connect localhost:8000 -tls1_1 < /dev/null
# Should fail with "no protocols available" or similar

# 5. Test hostname verification (should succeed)
curl --cert certs/mcp/gateway/client.pem \
     --cacert certs/mcp/gateway/ca.crt \
     https://localhost:8000/health

# 6. Test without client cert (should fail if ssl_cert_reqs=2)
curl --cacert certs/mcp/gateway/ca.crt \
     https://localhost:8000/health
```

Files in this skill

  • README.md839 B
  • skill.md21.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.