Getting StartedAuthentication

Authentication

Syaala Platform uses API keys and JWT tokens for secure authentication across all services.

⚠️

Security First: Never commit API keys to version control. Always use environment variables or secure secret management.

Authentication Methods

Syaala supports three authentication methods:

  1. API Keys - For programmatic access (CLI, SDK, direct API calls)
  2. JWT Tokens - For dashboard and web applications
  3. Service Role Keys - For server-to-server communication (admin only)

API Keys

API keys provide long-lived authentication for automated systems, scripts, and integrations.

Creating an API Key

  1. Log into the Syaala Dashboard
  2. Navigate to Settings → API Keys
  3. Click “Create API Key”
  4. Enter a descriptive name (e.g., production-server, ci-cd-pipeline)
  5. Select permissions scope:
    • Full Access - All operations (deployments, billing, settings)
    • Deployments Only - Create, read, update, delete deployments
    • Read Only - View deployments and metrics (no writes)
  6. Click “Generate Key”
🚫

⚠️ Copy your API key immediately!

For security, we only show the key once. Store it securely - you won’t be able to see it again.

API Key Format

sk_live_1a2b3c4d5e6f7g8h9i0j  # Production key
sk_test_9z8y7x6w5v4u3t2s1r0q  # Development/testing key
  • Prefix: sk_live_ (production) or sk_test_ (development)
  • Length: 32 characters after prefix
  • Encoding: Base62 (alphanumeric)

Using API Keys

# Store in environment variable
export SYAALA_API_KEY="sk_live_1a2b3c4d5e6f7g8h9i0j"
 
# Authenticate CLI
syaala auth login --api-key "$SYAALA_API_KEY"
 
# Or authenticate interactively (prompts for key)
syaala auth login

Rotating API Keys

For security, rotate API keys every 90 days:

  1. Create a new API key with the same permissions
  2. Update all systems to use the new key
  3. Test that everything works with the new key
  4. Delete the old API key from Dashboard → Settings → API Keys

💡 Pro Tip: Use separate API keys for each environment (development, staging, production) and service (CI/CD, backend, cron jobs).


JWT Tokens (Dashboard Authentication)

The Syaala Dashboard uses Supabase authentication with JWT tokens.

Login Flow

  1. Email/Password Login:

    POST https://platform.syaala.com/api/auth/login
    Content-Type: application/json
     
    {
      "email": "user@company.com",
      "password": "your-secure-password"
    }
  2. Response:

    {
      "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refresh_token": "v1.Ma7Ql3...",
      "expires_in": 3600,
      "token_type": "bearer",
      "user": {
        "id": "user-uuid",
        "email": "user@company.com",
        "organization_id": "org-uuid"
      }
    }
  3. Token Storage:

    • Access Token: Valid for 1 hour, stored in memory or httpOnly cookie
    • Refresh Token: Valid for 30 days, used to obtain new access tokens

Token Refresh

Access tokens expire after 1 hour. Use the refresh token to get a new one:

const response = await fetch('https://platform.syaala.com/api/auth/refresh', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    refresh_token: 'v1.Ma7Ql3...'
  })
})
 
const { access_token, refresh_token } = await response.json()

Using JWT Tokens

// In browser/dashboard
const response = await fetch('https://platform.syaala.com/api/deployments', {
  headers: {
    'Authorization': `Bearer ${accessToken}`,
    'Content-Type': 'application/json'
  }
})

Service Role Keys (Admin Only)

Service role keys bypass Row-Level Security (RLS) and have full database access.

🚫

🔴 DANGER: Service Role Keys

  • Never expose service role keys in client-side code
  • Only use in trusted server environments
  • Rotate immediately if compromised
  • Log all service role key usage

When to Use

  • Database migrations - Applying schema changes
  • Admin operations - Bulk user management, organization setup
  • System scripts - Automated cleanup, billing reconciliation

Retrieving Service Role Key

  1. Log into Supabase Dashboard
  2. Select your project: fvpedpplixboccfyoewv
  3. Navigate to Settings → API
  4. Copy service_role key (not anon key!)

Using Service Role Keys

import { createClient } from '@supabase/supabase-js'
 
const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.SUPABASE_SERVICE_ROLE_KEY!, // NEVER expose this!
  {
    auth: {
      autoRefreshToken: false,
      persistSession: false
    }
  }
)
 
// Bypass RLS - full database access
const { data: allUsers } = await supabase
  .from('users')
  .select('*')

Security Best Practices

Environment Variables

DO use environment variables:

# .env (NEVER commit this file!)
SYAALA_API_KEY=sk_live_1a2b3c4d5e6f7g8h9i0j
SYAALA_ORG_ID=org_abc123xyz
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
// ✅ CORRECT
const apiKey = process.env.SYAALA_API_KEY
 
// ❌ WRONG - Never hardcode!
const apiKey = "sk_live_1a2b3c4d5e6f7g8h9i0j"

Secret Management

For production environments, use proper secret management:

  • Vercel: Environment Variables UI
  • AWS: AWS Secrets Manager
  • GCP: Secret Manager
  • Kubernetes: Sealed Secrets or External Secrets Operator

Least Privilege

Grant minimum required permissions:

Use CaseRecommended Permission
CI/CD pipelineDeployments Only
Monitoring dashboardRead Only
Admin scriptsFull Access
Customer integrationsDeployments Only

Audit Logging

All API key usage is logged in the audit_logs table:

SELECT
  action,
  resource_type,
  resource_id,
  user_id,
  api_key_id,
  ip_address,
  created_at
FROM audit_logs
WHERE api_key_id = 'key_abc123'
ORDER BY created_at DESC
LIMIT 100;

Rate Limiting

API keys and JWT tokens are subject to rate limits:

PlanRate LimitBurst
Free60 requests/minute100 requests
Startup600 requests/minute1,000 requests
Growth6,000 requests/minute10,000 requests
EnterpriseCustomCustom

Rate Limit Headers

API responses include rate limit information:

HTTP/1.1 200 OK
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 587
X-RateLimit-Reset: 1728003600

Handling Rate Limits

const response = await fetch('/api/deployments')
 
const remaining = parseInt(response.headers.get('X-RateLimit-Remaining') || '0')
const resetTime = parseInt(response.headers.get('X-RateLimit-Reset') || '0')
 
if (response.status === 429) {
  const waitSeconds = resetTime - Math.floor(Date.now() / 1000)
  console.log(`Rate limited. Retry after ${waitSeconds} seconds`)
  await new Promise(resolve => setTimeout(resolve, waitSeconds * 1000))
  // Retry request...
}

Troubleshooting

Invalid API Key

Error: 401 Unauthorized: Invalid API key

Causes:

  • API key is incorrect or has a typo
  • API key has been deleted or revoked
  • Using sk_test_ key in production environment

Solution: Verify the API key in Dashboard → Settings → API Keys

Token Expired

Error: 401 Unauthorized: Token expired

Causes:

  • Access token has expired (1-hour lifetime)
  • Refresh token has expired (30-day lifetime)

Solution: Use the refresh token to obtain a new access token

Insufficient Permissions

Error: 403 Forbidden: Insufficient permissions

Causes:

  • API key has “Read Only” permissions but trying to create a deployment
  • User account lacks organization admin privileges

Solution: Use an API key with appropriate permissions or contact your organization admin


Next Steps

Now that you understand authentication, you’re ready to: