Terraform Cloud Backend

OpenTaco provides full compatibility with Terraform’s cloud backend configuration, offering a self-hosted alternative to Terraform Cloud. This enables teams to use the familiar cloud block syntax while maintaining control over their infrastructure state.

Overview

The cloud backend support in OpenTaco includes:
  • Terraform Cloud API compatibility - Full /tfe/api/v2 endpoint implementation
  • OAuth2/PKCE authentication - Secure login flow compatible with terraform login
  • Workspace management - Create, read, update, and manage workspaces
  • State locking and versioning - Advanced state management with atomic operations
  • RBAC integration - Fine-grained permissions for workspace access
  • Service discovery - Automatic configuration via /.well-known/terraform.json

Quick Start

1. Configure Your Terraform Project

Add a cloud block to your Terraform configuration:
terraform {
  cloud {
    hostname = "localhost:8080"  # Your OpenTaco server
    
    workspaces {
      name = "my-app-production"
    }
  }
}

2. Login to OpenTaco

Use the Terraform CLI to authenticate:
terraform login localhost:8080
This will:
  1. Open your browser to OpenTaco’s OAuth2 flow
  2. Authenticate with your OIDC provider (if configured)
  3. Store credentials in ~/.terraform.d/credentials.tfrc.json
  4. Automatically work with all taco CLI commands - no need for separate taco login!

3. Initialize and Apply

terraform init
terraform plan
terraform apply
OpenTaco will automatically manage workspace creation, state storage, and locking.

Cloud Block Configuration

Single Workspace

terraform {
  cloud {
    hostname = "your-opentaco-server.com"
    
    workspaces {
      name = "my-workspace"
    }
  }
}

Workspace Tags (Multiple Workspaces)

terraform {
  cloud {
    hostname = "your-opentaco-server.com"
    organization = "my-org"  # Optional
    
    workspaces {
      tags = ["app:web", "env:production"]
    }
  }
}

Authentication Flow

OpenTaco implements the full Terraform login protocol with a hybrid token model designed for production HA deployments:

Service Discovery

OpenTaco exposes /.well-known/terraform.json which tells Terraform where to find:
  • OAuth2 authorization endpoint
  • Token exchange endpoint
  • API endpoints

OAuth2 with PKCE

The authentication flow follows OAuth2 with PKCE (Proof Key for Code Exchange):
  1. Authorization Request - Terraform generates a code challenge and redirects to OpenTaco
  2. User Authentication - User authenticates with configured OIDC provider
  3. Authorization Code - OpenTaco returns an authorization code
  4. Token Exchange - Terraform exchanges the code for both token types
  5. API Access - Different tokens used for different API surfaces

Hybrid Token Model

OpenTaco uses a dual-token architecture that balances performance, security, and compatibility:

Opaque API Tokens (/tfe/api/v2/*)

  • Format: otc_tfe_<random> (stored in S3 or memory)
  • Lifetime: No expiry (manually revoked like Terraform Cloud)
  • Use Case: Terraform CLI interactions, workspace management
  • Benefits: Individual revocation, audit trail, TFC compatibility
  • Storage: S3-backed for HA, memory fallback for development

JWT Tokens (/v1/* Management API)

  • Format: EdDSA (Ed25519) signed JSON Web Tokens
  • Lifetime: Short-lived (1 hour default, configurable)
  • Use Case: Internal management operations, taco CLI
  • Benefits: Stateless verification, high performance, no storage dependency
  • Verification: Local signature validation using JWKS

SigV4 Authentication (/s3/* S3-Compatible API)

  • Format: AWS Signature Version 4
  • Tokens: Short-lived STS credentials (JWT in session token)
  • Use Case: S3-compatible state backend
  • Benefits: Standard AWS tooling compatibility

Industry Alignment

Design Rationale

This hybrid approach follows established patterns across the infrastructure industry:
  • Terraform Cloud: Long-lived opaque API tokens for CLI access
  • GitHub: Personal access tokens (opaque) + JWT for apps
  • AWS: Long-lived access keys + short-lived session tokens
  • Kubernetes: Service account tokens (JWT) + API tokens (opaque)
  • Docker Hub: API tokens (opaque) + JWT for internal services
Why Not Just JWTs Everywhere?
  • Terraform CLI expects non-expiring tokens (no refresh mechanism)
  • JWT key rotation affects ALL tokens simultaneously (poor incident response)
  • S3 dependency for revocation would be required anyway for individual control
Why Not Just Opaque Everywhere?
  • Every API call → S3 lookup (performance cost)
  • S3 dependency becomes single point of failure
  • Higher operational overhead (token cleanup, caching, etc.)
Benefits of Hybrid Model:
  • TFE compatibility - Matches Terraform Cloud behavior exactly
  • Performance optimization - Fast JWT validation for high-volume APIs
  • HA deployment - Stateless where beneficial, stateful where needed
  • Individual revocation - Per-token control for security incidents
  • Operational flexibility - Different token lifetimes per use case
  • Clean upgrade path - Can consolidate to single model if requirements change
This design optimizes for real-world production requirements while maintaining compatibility with existing tooling and expectations.

Stateless OAuth Implementation

OpenTaco implements a fully stateless OAuth2 + PKCE flow using industry-standard JWT tokens and encrypted session state:

Architecture Overview

  1. JWT Authorization Codes - Cryptographically signed tokens using EdDSA (Ed25519)
  2. Encrypted OAuth Sessions - AES-256-GCM encrypted session data in state parameters
  3. Load Balancer Compatible - Any server instance can handle any step of the OAuth flow
  4. Auto-Expiring - All tokens expire automatically (5 minutes) without cleanup processes
  5. Key Rotation Support - JWT key IDs enable seamless key rotation

JWT Signing Key Configuration

OpenTaco uses EdDSA (Ed25519) keys to sign JWT authorization codes. All server instances must use the same signing key pair: Development (Ephemeral Keys):
# No configuration needed - keys are generated automatically
./opentacosvc
Production (Persistent Keys):
# Generate Ed25519 key pair
openssl genpkey -algorithm Ed25519 -out opentaco-jwt-key.pem

# Configure all server instances with the same key
export OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH="/path/to/opentaco-jwt-key.pem"
export OPENTACO_TOKENS_KID="v1"  # Key ID for rotation

# Optional: Custom issuer and TTLs
export OPENTACO_PUBLIC_BASE_URL="https://your-opentaco-server.com"
export OPENTACO_TOKENS_ACCESS_TTL="1h"
export OPENTACO_TOKENS_REFRESH_TTL="720h"

./opentacosvc

OAuth State Encryption Key Configuration

For OAuth session state encryption, all server instances must share the same encryption key:
# Generate a secure random key (32+ characters recommended)
openssl rand -base64 32

# Set the environment variable on all server instances
export OPENTACO_OAUTH_STATE_KEY="your-generated-key-here"

# Start the server
./opentacosvc

Key Management Best Practices

Development:
# Minimal configuration - keys auto-generated
export OPENTACO_OAUTH_STATE_KEY="k8s3m9xP2vQ7wE1rT6yU4iO5pL0aSd8fG3hJ9nB2cV5m"
./opentacosvc
Production with Kubernetes:
apiVersion: v1
kind: Secret
metadata:
  name: opentaco-keys
type: Opaque
data:
  jwt-private-key.pem: LS0tLS1CRUdJTi... # Base64 encoded Ed25519 private key
stringData:
  oauth-state-key: "your-production-oauth-state-key-here"
---
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: opentaco
        env:
        - name: OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH
          value: "/etc/keys/jwt-private-key.pem"
        - name: OPENTACO_TOKENS_KID
          value: "v1"
        - name: OPENTACO_OAUTH_STATE_KEY
          valueFrom:
            secretKeyRef:
              name: opentaco-keys
              key: oauth-state-key
        - name: OPENTACO_PUBLIC_BASE_URL
          value: "https://opentaco.example.com"
        volumeMounts:
        - name: keys
          mountPath: /etc/keys
          readOnly: true
      volumes:
      - name: keys
        secret:
          secretName: opentaco-keys
          items:
          - key: jwt-private-key.pem
            path: jwt-private-key.pem
            mode: 0400
Production with Secret Management:
# AWS Secrets Manager example
export OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH="/tmp/jwt-key.pem"
aws secretsmanager get-secret-value --secret-id opentaco-jwt-key --query SecretBinary --output text | base64 -d > /tmp/jwt-key.pem
export OPENTACO_OAUTH_STATE_KEY="$(aws secretsmanager get-secret-value --secret-id opentaco-oauth-key --query SecretString --output text)"

# HashiCorp Vault example  
vault kv get -field=jwt_key secret/opentaco > /tmp/jwt-key.pem
export OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH="/tmp/jwt-key.pem"
export OPENTACO_OAUTH_STATE_KEY="$(vault kv get -field=oauth_key secret/opentaco)"

Key Rotation Support

JWT Signing Key Rotation:
# Generate new key with new ID
openssl genpkey -algorithm Ed25519 -out opentaco-jwt-key-v2.pem

# Deploy with new key ID (gradually roll out across instances)
export OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH="/path/to/opentaco-jwt-key-v2.pem"
export OPENTACO_TOKENS_KID="v2"  # New tokens signed with v2

# Old v1 tokens remain valid until expiration (5 minutes for OAuth codes)
# JWKS endpoint serves both keys for verification
Benefits of JWT-based approach:
  • Seamless rotation - Old tokens verify until expiration
  • Multiple key support - JWKS can serve multiple public keys
  • Industry standard - Compatible with JWT tooling and debuggers
  • Cryptographic security - EdDSA signatures prevent tampering

Security Considerations

JWT Signing Keys:
  • Key Compromise - If private key is compromised, attackers can mint valid OAuth codes - rotate immediately
  • Key Distribution - All instances need the same private key, but only public key is exposed via JWKS
  • Rotation Impact - Graceful rotation supported; old tokens remain valid until natural expiration
  • Algorithm Security - EdDSA (Ed25519) provides quantum-resistant signatures
OAuth State Encryption Keys:
  • State Key Rotation - Changing encryption key invalidates in-flight OAuth sessions (5-minute impact)
  • Key Compromise - Attackers can forge OAuth session state - rotate both keys immediately
  • Shared Requirement - All instances must share identical encryption key
General Security:
  • Never Commit Keys - Keep all private keys out of version control and configuration files
  • File Permissions - JWT private keys should have restricted permissions (0400)
  • Key Storage - Use dedicated secret management systems in production
  • Audit Logging - Monitor key rotation events and OAuth failures

Troubleshooting

“Invalid or expired authorization code” errors:
  • Check JWT signing key consistency across all server instances
  • Verify OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH points to valid Ed25519 private key
  • Ensure system clocks are synchronized (JWT timestamps are validated)
  • Test JWT verification with online JWT debuggers using JWKS endpoint
“Invalid or expired state” errors:
  • Verify all server instances have identical OPENTACO_OAUTH_STATE_KEY
  • Check if encryption key was recently rotated (invalidates active sessions)
  • Ensure the key has sufficient entropy (use openssl rand -base64 32)
OAuth flow fails between load-balanced servers:
  • Confirm both JWT signing keys and OAuth encryption keys are identical across instances
  • Verify JWKS endpoint returns consistent public keys: GET /oidc/jwks.json
  • Test with single server instance to isolate load balancer issues
JWT signature verification fails:
# Check JWKS endpoint exposes correct public keys
curl http://localhost:8080/oidc/jwks.json

# Verify private key format and permissions
openssl pkey -in /path/to/jwt-key.pem -text -noout
ls -la /path/to/jwt-key.pem  # Should be 0400 permissions
Key rotation issues:
  • Verify new OPENTACO_TOKENS_KID is unique and matches the key
  • Check that old OAuth codes expire naturally (wait 5 minutes after rotation)
  • Monitor logs for JWT verification failures during rotation window

Workspace Operations

Workspace Lifecycle

OpenTaco supports all standard workspace operations:
# Workspaces are created automatically on first use
terraform workspace new my-new-workspace

# List available workspaces  
terraform workspace list

# Switch between workspaces
terraform workspace select staging

State Management

Each workspace maintains its own state with:
  • Atomic uploads - State changes are atomic and lock-protected
  • Version history - Full state version tracking
  • Rollback capability - Restore previous state versions
  • Checksums - Integrity verification for all state operations

Locking

OpenTaco provides robust state locking:
  • Automatic locking - State is locked during plan and apply
  • Lock metadata - Tracks who locked the state and when
  • Force unlock - Administrators can force unlock stuck states
  • Lock timeouts - Configurable lock timeout behavior

RBAC Integration

When RBAC is enabled, workspace access is controlled by permissions:

Permission Model

  • unit:read - Read workspace state and metadata
  • unit:write - Modify workspace state
  • unit:lock - Lock/unlock workspace state
  • unit:manage - Full workspace administration

Role Assignment

# Assign workspace access to users
./taco rbac users assign user@example.com reader my-workspace

# Create custom roles for workspace access
./taco rbac roles create workspace-admin \
  --description "Full workspace access"

./taco rbac roles workspace-admin permissions \
  --add unit:read,unit:write,unit:lock

API Endpoints

OpenTaco implements the Terraform Cloud API v2 specification:

Core Endpoints

MethodEndpointDescription
GET/tfe/api/v2/organizations/:org/workspaces/:nameGet workspace details
POST/tfe/api/v2/workspaces/:id/actions/lockLock workspace
POST/tfe/api/v2/workspaces/:id/actions/unlockUnlock workspace
GET/tfe/api/v2/workspaces/:id/current-state-versionGet current state
POST/tfe/api/v2/workspaces/:id/state-versionsCreate new state version

Authentication Endpoints

MethodEndpointDescription
GET/.well-known/terraform.jsonService discovery
GET/oauth/authorizationOAuth2 authorization
POST/oauth/tokenToken exchange
GET/oidc/jwks.jsonJWT public keys (JWKS)

Upload Endpoints

State upload endpoints are exempted from authentication middleware since Terraform doesn’t send auth headers during uploads. Security is maintained through:
  • Upload URLs are only provided to authenticated clients
  • Lock ownership validation
  • RBAC permission checks in handlers

Configuration Options

Essential Environment Variables

JWT Signing Keys (Required for Production)

# Ed25519 private key for JWT signing (all instances must share)
export OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH="/etc/keys/opentaco-jwt-key.pem"
export OPENTACO_TOKENS_KID="v1"  # Key ID for rotation

# Generate key: openssl genpkey -algorithm Ed25519 -out opentaco-jwt-key.pem

OAuth State Encryption (Required for HA)

# AES-256 key for encrypting OAuth session state (all instances must share)
export OPENTACO_OAUTH_STATE_KEY="your-32+-character-secure-random-key"

# Generate key: openssl rand -base64 32

Base URL (Required behind Load Balancers)

# Public URL for OAuth redirects (overrides request Host header)
export OPENTACO_PUBLIC_BASE_URL="https://opentaco.example.com"

OIDC Provider Configuration

# Required for external authentication
export OPENTACO_AUTH_ISSUER="https://your-provider.com"
export OPENTACO_AUTH_CLIENT_ID="your-client-id"
export OPENTACO_AUTH_CLIENT_SECRET="your-client-secret"  # For confidential clients

# Optional: explicit endpoints (auto-discovered if not set)
export OPENTACO_AUTH_AUTH_URL="https://your-provider.com/authorize"
export OPENTACO_AUTH_TOKEN_URL="https://your-provider.com/oauth/token"

Token Lifetime Configuration

# JWT access token lifetime (default: 1h)
export OPENTACO_TOKENS_ACCESS_TTL="2h"

# JWT refresh token lifetime (default: 720h/30 days)  
export OPENTACO_TOKENS_REFRESH_TTL="8760h"

# Terraform OAuth token lifetime (default: 1h, recommend longer for CLI)
export OPENTACO_TERRAFORM_TOKEN_TTL="720h"

# Note: Opaque TFE tokens never expire (manually revoked only)

Complete Configuration Examples

Development Setup

# Minimal configuration - keys auto-generated
export OPENTACO_AUTH_DEV_SKIP_VERIFY=true  # Skip OIDC for testing
export OPENTACO_OAUTH_STATE_KEY="dev-key-change-in-production-32b"
./opentacosvc

Production with Auth0

# JWT signing
export OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH="/etc/keys/jwt-key.pem"
export OPENTACO_TOKENS_KID="v1"

# OAuth encryption & public URL
export OPENTACO_OAUTH_STATE_KEY="$(openssl rand -base64 32)"
export OPENTACO_PUBLIC_BASE_URL="https://opentaco.company.com"

# OIDC provider
export OPENTACO_AUTH_ISSUER="https://company.us.auth0.com"
export OPENTACO_AUTH_CLIENT_ID="your-auth0-client-id"
export OPENTACO_AUTH_CLIENT_SECRET="your-auth0-client-secret"

# Token lifetimes
export OPENTACO_TERRAFORM_TOKEN_TTL="720h"  # 30 days for CLI comfort

./opentacosvc -storage s3

Production with WorkOS

# JWT signing  
export OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH="/etc/keys/jwt-key.pem"
export OPENTACO_TOKENS_KID="v1"

# OAuth encryption & public URL
export OPENTACO_OAUTH_STATE_KEY="$(cat /etc/secrets/oauth-key)"
export OPENTACO_PUBLIC_BASE_URL="https://opentaco.company.com"

# WorkOS OIDC
export OPENTACO_AUTH_ISSUER="https://api.workos.com/user_management"
export OPENTACO_AUTH_CLIENT_ID="your-workos-client-id"
export OPENTACO_AUTH_CLIENT_SECRET="your-workos-client-secret"
# Auth/token URLs auto-detected for WorkOS

./opentacosvc -storage s3

Token Lifecycle and Management

Terraform Login Flow

When you run terraform login your-host, the OAuth flow issues both token types:
{
  "access_token": "eyJ0eXAiOiJKV1Qi...",  // JWT for internal APIs
  "token": "otc_tfe_abc123...",           // Opaque for TFE APIs  
  "token_type": "Bearer",
  "expires_in": 2592000,                  // JWT expiry (30 days if configured)
  "scope": "api s3"
}
Terraform CLI stores the opaque token (token field) and uses it for all /tfe/api/v2/* operations.

Authentication Requirements by API Surface

API SurfaceToken TypeAuthentication MethodUse Case
/tfe/api/v2/*OpaqueAuthorization: Bearer otc_tfe_...Terraform CLI operations
/v1/*JWTAuthorization: Bearer eyJ0eXA...taco CLI, management
/s3/*SigV4AWS signature with JWT session tokenS3-compatible backend
This means:
  • terraform login → Terraform CLI works immediately
  • ⚠️ taco login → Still required for /v1/* management operations

Token Storage Locations

Terraform Credentials:
~/.terraform.d/credentials.tfrc.json
{
  "credentials": {
    "your-host": {
      "token": "otc_tfe_abc123..."  // Opaque token
    }
  }
}
Taco Credentials:
~/.config/opentaco/credentials.json  
{
  "profiles": {
    "https://your-host": {
      "access_token": "eyJ0eXAiOiJKV1Qi...",  // JWT
      "refresh_token": "eyJhbGciOiJFZERTQS..."
    }
  }
}

Token Revocation

Opaque TFE Tokens:
# Individual token revocation (planned feature)
curl -X DELETE https://your-host/v1/auth/tokens/otc_tfe_abc123 \
  -H "Authorization: Bearer your-admin-jwt"

# Currently: revoke by rotating JWT signing key (affects all JWTs)
JWT Tokens:
  • Revoked by rotating the JWT signing key (OPENTACO_TOKENS_KID)
  • Short-lived by design (1 hour default)
  • Refresh tokens can be individually invalidated (planned feature)

High Availability Considerations

Shared Secrets (Critical): All server instances must share these identical values:
OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH="/etc/keys/same-key.pem"
OPENTACO_TOKENS_KID="v1"
OPENTACO_OAUTH_STATE_KEY="same-32-char-key-across-instances"
Storage Backend:
  • Opaque tokens: Stored in S3 (HA-safe) or memory (dev only)
  • JWT verification: Stateless (no storage required)
  • OAuth sessions: Encrypted in URL state parameter (stateless)
Load Balancer Configuration:
  • Set OPENTACO_PUBLIC_BASE_URL to the public-facing URL
  • Ensure health checks hit /healthz
  • No session affinity required (fully stateless)

Migration from Terraform Cloud

Export from Terraform Cloud

  1. Download state files from Terraform Cloud workspaces
  2. Note workspace configurations and variables
  3. Export team and user permissions

Import to OpenTaco

  1. Configure cloud blocks to point to OpenTaco
  2. Initialize workspaces with terraform init
  3. Import existing state files:
# Option 1: Direct state import
terraform state push terraform.tfstate

# Option 2: Configure and apply
terraform init -reconfigure
terraform plan  # Verify state matches

RBAC Migration

Configure equivalent permissions in OpenTaco:
# Recreate teams as roles
./taco rbac roles create developers
./taco rbac roles create administrators

# Assign workspace permissions  
./taco rbac users assign user@example.com developers my-workspace

Troubleshooting

Common Authentication Issues

“JWT signer not available” during OAuth:
# Check JWT key exists and is readable
ls -la $OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH
openssl pkey -in $OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH -text -noout

# Or use ephemeral keys for development
unset OPENTACO_TOKENS_PRIVATE_KEY_PEM_PATH
“Invalid redirect_uri” during terraform login:
# Ensure redirect validation allows your setup
# Current validation: http://127.0.0.1|localhost|::1:10000-10010/any-path

# Check OAuth debug endpoint
curl -s http://localhost:8080/oauth/debug | jq
“Invalid client_id” errors:
# Client ID validation is now permissive - any non-empty value accepted
# Check your OIDC provider configuration
echo $OPENTACO_AUTH_CLIENT_ID
echo $OPENTACO_AUTH_CLIENT_SECRET
OIDC token exchange failures:
# Check OIDC configuration
curl -s http://localhost:8080/v1/auth/config | jq

# Verify OIDC provider endpoints are reachable
curl -s $OPENTACO_AUTH_ISSUER/.well-known/openid_configuration | jq

# For Auth0, ensure Domain and Client credentials are correct
# For WorkOS, endpoints are auto-detected from issuer URL
Opaque token verification failures:
# Check if S3 storage is working
aws s3 ls s3://your-bucket/your-prefix/_tfe_tokens/

# Verify token exists and is valid JSON
aws s3 cp s3://your-bucket/your-prefix/_tfe_tokens/otc_tfe_xyz.json - | jq

# Check token status directly
curl -H "Authorization: Bearer otc_tfe_xyz" http://localhost:8080/tfe/api/v2/ping

HA Deployment Issues

Authentication works on one server but not others:
# Ensure all instances share the same keys
# JWT signing key must be identical
diff /etc/keys/jwt-key.pem /path/to/other/instance/jwt-key.pem

# OAuth state encryption key must be identical  
echo $OPENTACO_OAUTH_STATE_KEY

# Check JWKS consistency across instances
curl -s https://instance1/oidc/jwks.json | jq .keys[0].kid
curl -s https://instance2/oidc/jwks.json | jq .keys[0].kid
OAuth state decryption failures:
# Usually means OPENTACO_OAUTH_STATE_KEY differs between instances
# Or user hit different servers during OAuth flow with different keys

# Verify state key is 32+ characters and identical across instances
echo $OPENTACO_OAUTH_STATE_KEY | wc -c  # Should be 45+ chars (base64 encoded)

Load Balancer Configuration Issues

OAuth redirects to wrong URL:
# Set explicit public base URL
export OPENTACO_PUBLIC_BASE_URL="https://your-public-domain.com"

# Or ensure load balancer sets headers correctly
# X-Forwarded-Proto: https
# X-Forwarded-Host: your-public-domain.com
Health check failures:
# Use proper health check endpoints
curl -s http://localhost:8080/healthz  # Should return 200
curl -s http://localhost:8080/readyz   # Should return 200

# Avoid hitting auth-protected endpoints for health checks

Token and Credential Issues

Terraform CLI shows “invalid credentials”:
# Check stored token format and validity
cat ~/.terraform.d/credentials.tfrc.json | jq .credentials

# Test token directly
TOKEN=$(jq -r '.credentials["your-host"].token' ~/.terraform.d/credentials.tfrc.json)
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/tfe/api/v2/ping

# Re-authenticate if token is invalid
terraform login -force your-host
taco CLI can’t authenticate:
# Check taco credentials separately
cat ~/.config/opentaco/credentials.json | jq

# taco login required for /v1 API access
./taco login --server https://your-host

# Debug which credentials are being used
./taco whoami --server https://your-host
Mixed credential issues:
# taco CLI tries Terraform credentials first if both exist
# Force taco to use its own credentials by removing terraform ones temporarily
mv ~/.terraform.d/credentials.tfrc.json ~/.terraform.d/credentials.tfrc.json.backup
./taco unit ls  # Should use taco credentials
mv ~/.terraform.d/credentials.tfrc.json.backup ~/.terraform.d/credentials.tfrc.json

Debug Logging

Enable comprehensive debugging:
# Server-side debugging
export OPENTACO_LOG_LEVEL=debug
./opentacosvc -storage s3

# Monitor authentication flows
tail -f /var/log/opentaco.log | grep -E "(AUTH|OAUTH|JWT|TFE)"

# Client-side debugging
export TF_LOG=DEBUG  # Terraform debug logs
terraform login localhost:8080
Common log messages and meanings:
"JWT: Loading Ed25519 private key" → Key loading successful
"OAuth: Using custom state encryption key" → State encryption configured  
"Failed to create JWT signer" → Check key file path and permissions
"OIDC: Configuration loaded" → External OIDC provider configured correctly
"Token verification failed" → Check token format and signing key consistency

Security Considerations

Network Security

  • Use HTTPS in production environments
  • Configure proper firewall rules for OpenTaco server
  • Consider VPN or private network access

Authentication Security

  • Use strong OIDC providers (WorkOS, Auth0, etc.)
  • Configure token expiration appropriately
  • Rotate signing keys periodically

State Security

  • Enable encryption at rest for S3 storage
  • Use IAM roles with minimal required permissions
  • Audit workspace access regularly

RBAC Security

  • Follow principle of least privilege
  • Regular review of user permissions
  • Use groups/roles rather than direct user assignments
  • Monitor permission changes through audit logs