NOTE - This feature requires provider-services version 0.8.0 or higher.
This guide explains how to enable automatic Let’s Encrypt certificate issuance for JWT (JSON Web Token) authentication in your Akash provider using Helm charts. This feature allows your provider to automatically obtain and manage SSL/TLS certificates for secure JWT token validation.
The guide is broken down into the following sections:
- Overview
- Prerequisites
- Configuration
- Complete Example Configuration
- Deployment
- Troubleshooting
- Testing
- Security Considerations
- Related Documentation
Overview
The Let’s Encrypt JWT certificate feature enables your Akash provider to:
- Automatically obtain SSL certificates from Let’s Encrypt
- Use HTTP-01 challenge validation by default (no configuration required)
- Support DNS-01 challenge validation as a backup option for wildcard certificates
- Support multiple DNS providers (Google Cloud DNS, Cloudflare) when using DNS validation
- Integrate with JWT authentication workflows
- Automatically renew certificates before expiration
Prerequisites
Before enabling Let’s Encrypt JWT certificates, ensure you have:
- Helm-based Akash Provider: Your provider must be deployed using the official Helm charts
- Kubernetes Cluster: A running Kubernetes cluster with the provider deployed
- Storage Class: Ensure your provider’s storage class attribute points to a valid storage class available in your cluster
- Public Domain: Your provider domain must be publicly accessible for HTTP-01 challenge validation
- DNS Provider Access (Optional): Only required if you want to use DNS-01 challenge validation for wildcard certificates
Configuration
HTTP Challenge (Default - Recommended)
The HTTP-01 challenge is now the default and recommended method. No additional configuration is required:
DNS Challenge (Optional)
If you need wildcard certificates or prefer DNS validation, you can configure DNS providers:
Cloudflare DNS Configuration
If you’re using Cloudflare DNS, add the following configuration:
letsEncrypt: enabled: true acme: caDirUrl: "https://acme-v02.api.letsencrypt.org/directory" dns: providers: - "cf" providers: cloudflare: enabled: true apiToken: "your-cloudflare-api-token"
Cloudflare DNS Setup Steps
-
Create API Token:
- Log into your Cloudflare dashboard
- Go to “My Profile” → “API Tokens”
- Click “Create Token”
- Use the “Custom token” template
-
Configure Token Permissions:
- Zone Resources: Include → All zones
- Zone Permissions: DNS
- Account Resources: Include → All accounts
- Account Permissions: Zone
-
Copy the Token: Replace
your-cloudflare-api-token
in yourprovider.yaml
with the actual token.
Google Cloud DNS Configuration
If you’re using Google Cloud DNS, add the following configuration:
letsEncrypt: enabled: true acme: caDirUrl: "https://acme-v02.api.letsencrypt.org/directory" dns: providers: - "gcloud" providers: googleCloud: enabled: true serviceAccount: content: | { "type": "service_account", "project_id": "your-project-id", "private_key_id": "your-private-key-id", "private_key": "-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY_HERE\n-----END PRIVATE KEY-----\n", "client_email": "[email protected]", "client_id": "your-client-id", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/your-service-account%40your-project-id.iam.gserviceaccount.com" }
Google Cloud DNS Setup Steps
-
Create a Service Account:
Terminal window gcloud iam service-accounts create akash-letsencrypt \--display-name="Akash Let's Encrypt DNS" -
Grant DNS Admin Role:
Terminal window gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \--member="serviceAccount:akash-letsencrypt@YOUR_PROJECT_ID.iam.gserviceaccount.com" \--role="roles/dns.admin" -
Create and Download Service Account Key:
Terminal window gcloud iam service-accounts keys create service-account.json \--iam-account=akash-letsencrypt@YOUR_PROJECT_ID.iam.gserviceaccount.com -
Copy the JSON Content: Replace the
content:
section in yourprovider.yaml
with the actual content of theservice-account.json
file.
Complete Example Configuration
Here’s a complete provider.yaml
example with Let’s Encrypt JWT certificates enabled using the default HTTP challenge:
---from: "akash1your-provider-address"key: "your-provider-key"keysecret: "your-key-secret"domain: "your-provider-domain.com"node: "https://rpc.your-network.com:443"withdrawalperiod: 12hprice_target_gpu_mappings: "rtx4000=80,*=110"chainid: your-networkattributes: - key: region value: "us-east" - key: host value: akash - key: tier value: community - key: organization value: "your-org" - key: capabilities/storage/1/class value: beta3 - key: capabilities/storage/1/persistent value: true - key: capabilities/gpu/vendor/nvidia/model/rtx4000 value: true - key: console/trials value: true - key: console/trials-registered value: "true"website: https://your-domain.combidmindeposit: "5000000uakt"
# Let's Encrypt JWT Certificate Configuration (HTTP Challenge - Default)letsEncrypt: enabled: true acme: caDirUrl: "https://acme-v02.api.letsencrypt.org/directory"
Deployment
Install/Upgrade Provider with Let’s Encrypt
-
Install the Provider (if not already installed):
Terminal window helm install akash-provider akash/provider -f provider.yaml -
Upgrade Existing Provider:
Terminal window helm upgrade akash-provider akash/provider -f provider.yaml
Verify Installation
-
Check Provider Pod Status:
Terminal window kubectl get pods -n akash-services | grep provider -
Check Let’s Encrypt Configuration:
Terminal window kubectl describe configmap akash-provider-letsencrypt -n akash-services -
Check Provider Logs:
Terminal window kubectl logs -n akash-services akash-provider-0 -f
Troubleshooting
Common Issues
1. HTTP Challenge Failed
Cause: Provider domain is not publicly accessible or firewall is blocking HTTP traffic. Solution:
- Ensure your provider domain is publicly accessible
- Check that port 80 is open and accessible
- Verify your domain DNS points to the correct IP address
2. Certificate Not Issued
Cause: HTTP challenge validation failed or domain not accessible. Solution:
- Verify your domain is publicly accessible
- Check that the provider service is running and accessible
- Review provider logs for specific error messages
3. Environment Variables Not Set
Cause: Let’s Encrypt configuration not properly applied.
Solution: Verify the letsEncrypt.enabled: true
is set in your configuration.
4. DNS Challenge Issues (If Using DNS)
Cause: DNS provider configuration is missing or incorrect. Solution:
- For Google Cloud: Verify the
serviceAccount.content
in yourprovider.yaml
contains valid JSON - For Cloudflare: Ensure the
apiToken
is correct and has proper permissions - Ensure the
dns.providers
list contains the correct provider name (gcloud
orcf
)
Debug Commands
-
Check Environment Variables:
Terminal window kubectl exec -n akash-services akash-provider-0 -- env | grep AP_CERT_ISSUER -
Check DNS Provider Secret (if using DNS challenge):
Terminal window kubectl get secret akash-provider-gcp-dns -n akash-services -o yaml -
Check Provider Command:
Terminal window kubectl logs -n akash-services akash-provider-0 | grep "Final command:"
Testing
Staging Environment
For testing, use the Let’s Encrypt staging environment:
letsEncrypt: enabled: true acme: caDirUrl: "https://acme-staging-v02.api.letsencrypt.org/directory" # Staging # ... rest of configuration
Production Environment
Once testing is complete, switch to production:
letsEncrypt: enabled: true acme: caDirUrl: "https://acme-v02.api.letsencrypt.org/directory" # Production # ... rest of configuration
Security Considerations
- API Token Security: Store Cloudflare API tokens securely and rotate them regularly
- Service Account Security: Use minimal required permissions for Google Cloud service accounts
- Email Notifications: Use a valid email address for Let’s Encrypt notifications
- Rate Limits: Be aware of Let’s Encrypt rate limits (50 certificates per registered domain per week)