Documentation Index
Fetch the complete documentation index at: https://mintlify.com/spiceai/spiceai/llms.txt
Use this file to discover all available pages before exploring further.
TLS/SSL Configuration
Spice.ai supports TLS (Transport Layer Security) encryption to secure communication between clients and the runtime. When enabled, TLS protects all endpoint traffic including HTTP, Flight SQL, and gRPC APIs.
Overview
TLS configuration in Spice provides:
- Encrypted communication: All data in transit is encrypted
- Certificate-based security: Standard X.509 certificate validation
- Multi-protocol support: Protects HTTP, Flight SQL, and gRPC endpoints
- Flexible configuration: Support for file-based and inline certificates
Configuration Methods
Method 1: Certificate Files
Reference certificate and key files on the filesystem:
version: v1
kind: Spicepod
name: my-app
runtime:
tls:
enabled: true
certificate_file: /path/to/certificate.pem
key_file: /path/to/private-key.pem
Method 2: Inline Certificates
Provide PEM-encoded certificates directly in the configuration:
runtime:
tls:
enabled: true
certificate: |
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKJ...
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhki...
-----END PRIVATE KEY-----
Method 3: Certificates from Secrets
Reference certificates stored in secret stores:
runtime:
tls:
enabled: true
certificate_file: ${secrets:TLS_CERT_PATH}
key_file: ${secrets:TLS_KEY_PATH}
Or with inline content from secrets:
runtime:
tls:
enabled: true
certificate: ${secrets:TLS_CERTIFICATE}
key: ${secrets:TLS_PRIVATE_KEY}
Method 4: Command-Line Arguments
Enable TLS with command-line flags:
spiced --tls-enabled \
--tls-certificate-file /path/to/cert.pem \
--tls-key-file /path/to/key.pem
Or with inline certificates:
spiced --tls-enabled \
--tls-certificate "$(cat certificate.pem)" \
--tls-key "$(cat private-key.pem)"
Configuration Priority
When multiple TLS configuration sources are provided, Spice uses this priority:
- Command-line arguments (
--tls-certificate-file, --tls-certificate)
- Spicepod configuration with secrets injection
- Direct spicepod configuration
Certificate Requirements
- Certificate: PEM-encoded X.509 certificate
- Private Key: PEM-encoded private key (RSA, ECDSA, or Ed25519)
Certificate Types
Spice supports:
- Self-signed certificates: For development and testing
- CA-signed certificates: For production environments
- Certificate chains: Including intermediate certificates
Generating Self-Signed Certificates
For development and testing:
# Generate private key
openssl genrsa -out key.pem 2048
# Generate self-signed certificate (valid for 365 days)
openssl req -new -x509 -key key.pem -out cert.pem -days 365 \
-subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"
Using Let’s Encrypt Certificates
For production with automatic certificate management:
# Install certbot
sudo apt-get install certbot
# Obtain certificate
sudo certbot certonly --standalone -d your-domain.com
# Certificates will be in:
# /etc/letsencrypt/live/your-domain.com/fullchain.pem
# /etc/letsencrypt/live/your-domain.com/privkey.pem
Then reference in your spicepod:
runtime:
tls:
enabled: true
certificate_file: /etc/letsencrypt/live/your-domain.com/fullchain.pem
key_file: /etc/letsencrypt/live/your-domain.com/privkey.pem
TLS with Different Endpoints
When TLS is enabled, all Spice endpoints use encrypted communication:
HTTP/REST API
# Without TLS (default)
curl http://localhost:3000/v1/sql -d "SELECT 1"
# With TLS
curl https://localhost:3000/v1/sql -d "SELECT 1"
# With self-signed certificate (development)
curl -k https://localhost:3000/v1/sql -d "SELECT 1"
Flight SQL
import pyarrow.flight as flight
# Without TLS
client = flight.FlightClient("grpc://localhost:50051")
# With TLS
client = flight.FlightClient("grpc+tls://localhost:50051")
# With self-signed certificate (development)
import grpc
options = [
('grpc.ssl_target_name_override', 'localhost'),
]
generic_options = []
for key, val in options:
generic_options.append(flight.FlightClientMiddlewareFactory.create_option(key, val))
client = flight.FlightClient(
"grpc+tls://localhost:50051",
generic_options=generic_options
)
gRPC
import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// With TLS
creds, err := credentials.NewClientTLSFromFile("cert.pem", "")
if err != nil {
log.Fatal(err)
}
conn, err := grpc.Dial(
"localhost:50052",
grpc.WithTransportCredentials(creds),
)
TLS with Secrets Management
Kubernetes Secrets
Store TLS certificates in Kubernetes secrets:
# Create secret from certificate files
kubectl create secret tls spice-tls-cert \
--cert=certificate.pem \
--key=private-key.pem
Mount the secret and reference in spicepod:
# Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: spice
spec:
template:
spec:
containers:
- name: spice
image: spiceai/spiceai:latest
volumeMounts:
- name: tls-certs
mountPath: /etc/spice/tls
readOnly: true
volumes:
- name: tls-certs
secret:
secretName: spice-tls-cert
---
# Spicepod configuration
runtime:
tls:
enabled: true
certificate_file: /etc/spice/tls/tls.crt
key_file: /etc/spice/tls/tls.key
Environment Variables
Store certificates in environment variables (for development):
export SPICE_TLS_CERT=$(cat certificate.pem)
export SPICE_TLS_KEY=$(cat private-key.pem)
runtime:
tls:
enabled: true
certificate: ${env:SPICE_TLS_CERT}
key: ${env:SPICE_TLS_KEY}
AWS Secrets Manager
Store certificates in AWS Secrets Manager:
# Store certificate
aws secretsmanager create-secret \
--name spice/tls/certificate \
--secret-string file://certificate.pem
# Store private key
aws secretsmanager create-secret \
--name spice/tls/private-key \
--secret-string file://private-key.pem
Configure secret store and reference:
secrets:
- name: aws
from: aws_secrets_manager:spice-secrets
runtime:
tls:
enabled: true
certificate: ${aws:tls-certificate}
key: ${aws:tls-private-key}
Complete Configuration Example
Production-ready configuration with TLS and authentication:
version: v1
kind: Spicepod
name: secure-app
secrets:
- name: env
from: env
runtime:
# TLS Configuration
tls:
enabled: true
certificate_file: /etc/spice/tls/cert.pem
key_file: /etc/spice/tls/key.pem
# API Key Authentication
auth:
api_key:
enabled: true
keys:
- ${env:SPICE_API_KEY_READONLY}:ro
- ${env:SPICE_API_KEY_READWRITE}:rw
datasets:
- from: postgres:production_db
name: customers
params:
pg_host: db.example.com
pg_port: "5432"
pg_db: production
pg_user: ${env:PG_USER}
pg_pass: ${env:PG_PASSWORD}
pg_sslmode: require # Require TLS for database connection
TLS Best Practices
1. Use CA-Signed Certificates in Production
Self-signed certificates should only be used for development and testing.
For production:
- Use certificates from a trusted Certificate Authority
- Consider Let’s Encrypt for free, automated certificates
- Use wildcard certificates for multiple subdomains
2. Secure Private Keys
- Store private keys with restrictive permissions (
chmod 600)
- Never commit private keys to version control
- Use secret management systems (Kubernetes Secrets, AWS Secrets Manager, etc.)
- Rotate certificates before expiration
# Set proper permissions
chmod 600 /path/to/private-key.pem
chown spice:spice /path/to/private-key.pem
3. Certificate Expiration Monitoring
Monitor certificate expiration:
# Check certificate expiration
openssl x509 -in certificate.pem -noout -enddate
# Check certificate details
openssl x509 -in certificate.pem -noout -text
Set up alerts for certificates expiring within 30 days.
4. Enable TLS for All Environments
While you may use self-signed certificates in development, always use TLS:
# Development
runtime:
tls:
enabled: true
certificate_file: ./dev-cert.pem
key_file: ./dev-key.pem
# Production
runtime:
tls:
enabled: true
certificate_file: /etc/letsencrypt/live/api.example.com/fullchain.pem
key_file: /etc/letsencrypt/live/api.example.com/privkey.pem
5. Combine with Authentication
Always use TLS with authentication:
runtime:
tls:
enabled: true
certificate_file: /path/to/cert.pem
key_file: /path/to/key.pem
auth:
api_key:
enabled: true
keys:
- ${secrets:API_KEY}:rw
6. Client Certificate Validation
Spice currently uses server-side TLS (runtime authenticates to clients). For mutual TLS (mTLS), consider using a reverse proxy like nginx or Envoy:
server {
listen 443 ssl;
ssl_certificate /path/to/server-cert.pem;
ssl_certificate_key /path/to/server-key.pem;
# Client certificate validation
ssl_client_certificate /path/to/ca.pem;
ssl_verify_client on;
location / {
proxy_pass https://spice:3000;
}
}
Troubleshooting
Certificate Validation Errors
# Error: certificate signed by unknown authority
# Solution: Add CA certificate to system trust store or use full chain
# Linux
sudo cp ca-certificate.pem /usr/local/share/ca-certificates/spice-ca.crt
sudo update-ca-certificates
# macOS
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ca-certificate.pem
# Convert PKCS#8 to traditional format if needed
openssl rsa -in key-pkcs8.pem -out key.pem
# Convert encrypted key to unencrypted (for Spice)
openssl rsa -in encrypted-key.pem -out unencrypted-key.pem
Certificate Chain Issues
Ensure your certificate file includes the full chain:
# Correct order in certificate.pem:
# 1. Server certificate
# 2. Intermediate certificate(s)
# 3. Root certificate (optional)
cat server-cert.pem intermediate-cert.pem > fullchain.pem
Checking TLS Configuration
Verify TLS is working:
# Test HTTPS endpoint
curl -v https://localhost:3000/health
# Test with openssl
openssl s_client -connect localhost:3000 -servername localhost
# Check certificate details
echo | openssl s_client -connect localhost:3000 2>/dev/null | \
openssl x509 -noout -text
TLS adds computational overhead:
- CPU Usage: Encryption/decryption increases CPU usage by 5-15%
- Latency: Adds ~1-5ms per request for handshake and encryption
- Throughput: Minimal impact on data transfer speeds
For high-throughput scenarios:
- Use hardware acceleration (AES-NI on modern CPUs)
- Enable HTTP/2 for connection reuse
- Consider TLS offloading with a reverse proxy