Authentication
All WAYSCloud API requests require authentication using API keys with Bearer token format. This guide covers authentication concepts, API key management, and security best practices.
Authentication Method
WAYSCloud uses Bearer token authentication. Every API request must include your API key in the Authorization header.
Bearer Token Format
Authorization: Bearer wayscloud_{service}_{id}_{secret}
Components:
wayscloud_- Prefix identifying WAYSCloud keys{service}- Service identifier (storage, llm, database, dns, gpu){id}- Unique key identifier{secret}- Secret key for authentication
Example Request
curl -X GET "https://api.wayscloud.services/v1/storage/" \
-H "Authorization: Bearer wayscloud_storage_abc123_XyZ789SecretKey"
Base URLs
All WAYSCloud services use the same base URL with service-specific paths:
https://api.wayscloud.services/v1/{service}
| Service | Base URL | Description |
|---|---|---|
| Storage | https://api.wayscloud.services/v1/storage | S3-compatible object storage |
| LLM | https://api.wayscloud.services/v1 | OpenAI-compatible endpoints |
| Database | https://api.wayscloud.services/v1/databases | PostgreSQL/MariaDB management |
| DNS | https://api.wayscloud.services/v1/dns | DNS zone and record management |
| GPU | https://api.wayscloud.services/v1/gpu | GPU-accelerated services |
API Key Types
Storage API Keys
Format: wayscloud_storage_{id}_{secret}
Permissions:
- Upload/download/delete objects
- List buckets and objects
- Get object metadata
Example:
curl -X PUT "https://api.wayscloud.services/v1/storage/my-bucket/file.txt" \
-H "Authorization: Bearer wayscloud_storage_abc123_YourSecretKey" \
--data-binary @file.txt
LLM API Keys
Format: wayscloud_llm_{id}_{secret}
Permissions:
- Chat completions
- List models
- Streaming responses
Example:
curl -X POST "https://api.wayscloud.services/v1/chat/completions" \
-H "Authorization: Bearer wayscloud_llm_xyz789_YourSecretKey" \
-H "Content-Type: application/json" \
-d '{"model": "qwen3-80b-instruct", "messages": [{"role": "user", "content": "Hello"}]}'
Database API Keys
Format: wayscloud_database_{id}_{secret}
Permissions:
- Create/delete databases
- Manage snapshots
- Configure backups
- Manage firewall rules
Example:
curl -X POST "https://api.wayscloud.services/v1/databases" \
-H "Authorization: Bearer wayscloud_database_def456_YourSecretKey" \
-H "Content-Type: application/json" \
-d '{"db_type": "postgresql", "db_name": "my_app_db"}'
DNS API Keys
Format: wayscloud_dns_{id}_{secret}
Permissions:
- Create/update/delete DNS records
- Manage zones
- Configure DNSSEC
Example:
curl -X POST "https://api.wayscloud.services/v1/dns/zones" \
-H "Authorization: Bearer wayscloud_dns_ghi789_YourSecretKey" \
-H "Content-Type: application/json" \
-d '{"domain": "example.com", "dnssec_enabled": true}'
GPU API Keys
Format: wayscloud_gpu_{id}_{secret}
Permissions:
- Create GPU jobs (video, TTS, transcription)
- Check job status
- Download results
Example:
curl -X POST "https://api.wayscloud.services/v1/gpu/jobs" \
-H "Authorization: Bearer wayscloud_gpu_jkl012_YourSecretKey" \
-H "Content-Type: application/json" \
-d '{"job_type": "video_generation", "prompt": "Ocean waves at sunset"}'
Creating API Keys
Via Dashboard (Recommended)
- Log in to my.wayscloud.services
- Navigate to API Keys in the sidebar
- Click Create New API Key
- Select service(s) and configure:
- Name: Descriptive name for the key
- Services: Select which APIs this key can access
- Description: Optional notes about usage
- IP Whitelist: Optional IP restrictions
- Click Create
- Copy the API key immediately - it won't be shown again
API keys are only shown once during creation. Store them securely in a password manager or secrets management system.
Via API (Programmatic)
Create keys programmatically using your Keycloak token:
curl -X POST "https://provision.wayscloud.net/api/v1/dashboard/api-keys" \
-H "Authorization: Bearer {keycloak_token}" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Storage Key",
"service": "storage",
"description": "Production environment storage access"
}'
Security Best Practices
✅ Do
-
Store keys securely
- Use environment variables
- Use secrets management (Vault, AWS Secrets Manager)
- Use password managers for personal keys
-
Rotate keys regularly
- Create new keys every 90 days
- Delete old keys after rotation
- Use different keys per environment
-
Use least privilege
- Create separate keys per service
- Use different keys for dev/staging/production
- Revoke keys when no longer needed
-
Monitor usage
- Check API usage in dashboard
- Set up billing alerts
- Review access logs
❌ Don't
-
Never commit keys to version control
# Bad - API key in code
api_key = "wayscloud_storage_abc123_Secret"
# Good - API key from environment
api_key = os.getenv('WAYSCLOUD_API_KEY') -
Never share keys
- Don't send keys via email or chat
- Don't share keys across teams
- Create separate keys per user/application
-
Never hardcode keys
// Bad - hardcoded API key
const apiKey = 'wayscloud_llm_xyz789_Secret';
// Good - from environment
const apiKey = process.env.WAYSCLOUD_API_KEY; -
Never log keys
- Sanitize logs to remove API keys
- Don't include keys in error messages
- Be careful with debug output
Using API Keys in Code
Python
import os
import requests
# Load from environment
API_KEY = os.getenv('WAYSCLOUD_API_KEY')
if not API_KEY:
raise ValueError("WAYSCLOUD_API_KEY not set")
# Make request
headers = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.wayscloud.services/v1/storage/',
headers=headers
)
JavaScript (Node.js)
const axios = require('axios');
// Load from environment
const API_KEY = process.env.WAYSCLOUD_API_KEY;
if (!API_KEY) {
throw new Error('WAYSCLOUD_API_KEY not set');
}
// Make request
const response = await axios.get(
'https://api.wayscloud.services/v1/storage/',
{
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
}
);
PHP
<?php
$apiKey = getenv('WAYSCLOUD_API_KEY');
if (!$apiKey) {
throw new Exception('WAYSCLOUD_API_KEY not set');
}
$ch = curl_init('https://api.wayscloud.services/v1/storage/');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
?>
Go
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
apiKey := os.Getenv("WAYSCLOUD_API_KEY")
if apiKey == "" {
panic("WAYSCLOUD_API_KEY not set")
}
client := &http.Client{}
req, _ := http.NewRequest("GET",
"https://api.wayscloud.services/v1/storage/", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
Environment Variables
Linux/macOS
# Add to ~/.bashrc or ~/.zshrc
export WAYSCLOUD_API_KEY="wayscloud_storage_abc123_YourSecretKey"
# Or use .env file
echo 'WAYSCLOUD_API_KEY=wayscloud_storage_abc123_YourSecretKey' > .env
Windows (PowerShell)
# Current session
$env:WAYSCLOUD_API_KEY = "wayscloud_storage_abc123_YourSecretKey"
# Permanent
[System.Environment]::SetEnvironmentVariable(
'WAYSCLOUD_API_KEY',
'wayscloud_storage_abc123_YourSecretKey',
'User'
)
Docker
# Dockerfile
ENV WAYSCLOUD_API_KEY=${WAYSCLOUD_API_KEY}
# docker run
docker run -e WAYSCLOUD_API_KEY="wayscloud_storage_abc123_YourSecretKey" myapp
# docker-compose.yml
services:
app:
environment:
- WAYSCLOUD_API_KEY=${WAYSCLOUD_API_KEY}
Managing API Keys
Listing Keys
View all keys in the dashboard at my.wayscloud.services/api-keys:
- Name and description
- Service permissions
- Creation date
- Last used date
Revoking Keys
If a key is compromised or no longer needed:
- Go to API Keys in dashboard
- Find the key to revoke
- Click Revoke or Delete
- Confirm the action
Revoking is immediate and cannot be undone. All applications using that key will stop working.
Key Rotation
Best practice: Rotate keys every 90 days
- Create a new API key with same permissions
- Update applications to use new key
- Test thoroughly in staging
- Deploy to production
- Delete old key after 7-day grace period
API Key Scopes
Each key has specific scopes based on selected services:
| Service | Scope | Endpoints |
|---|---|---|
| Storage | storage:read | GET, HEAD |
| Storage | storage:write | PUT, POST |
| Storage | storage:delete | DELETE |
| LLM | llm:inference | POST /v1/chat/completions |
| LLM | llm:models | GET /v1/models |
| Database | database:manage | All database endpoints |
| DNS | dns:manage | All DNS endpoints |
| GPU | gpu:use | All GPU endpoints |
Authentication Errors
401 Unauthorized
{
"error": "Invalid or expired API key",
"code": "AUTH_FAILED"
}
Causes:
- Incorrect API key
- Revoked API key
- Missing
Bearerprefix - Extra spaces in header
Solution: Verify key format and check if key is active in dashboard.
403 Forbidden
{
"error": "API key does not have permission for this service",
"code": "INSUFFICIENT_PERMISSIONS"
}
Causes:
- Using wrong service key (e.g., storage key for LLM API)
- Key doesn't have required permissions
Solution: Create new API key with correct service permissions.
Next Steps
- Error Handling - Common errors across all services
- Rate Limits - Rate limits per service
- Creating API Keys - Detailed key creation guide
Support
Authentication issues? Contact us:
- Email: support@wayscloud.no
- Documentation: https://docs.wayscloud.services
- Dashboard: https://my.wayscloud.services