Authentication
Uranus supports multiple authentication methods to secure agent access.
Overview
Authentication layers:
- Cloudflare Access - Enterprise SSO integration
- Email-Based Access - Role-based agent permissions
- API Keys - Service integrations
Cloudflare Access
Setup
- Enable Cloudflare Access for your domain
- Configure identity provider (Okta, Google, Azure AD, etc.)
- Create an Access application for Uranus
- Set the audience tag in
wrangler.toml:
toml
[vars]
CF_ACCESS_AUD = "your-access-audience-tag"JWT Validation
The worker validates Cloudflare Access JWTs:
typescript
async function validateAccessJWT(request: Request, env: Env) {
const jwt = request.headers.get('CF-Access-JWT-Assertion')
if (!jwt) {
return null
}
// Validate JWT against Cloudflare Access
const payload = await verifyJWT(jwt, env.CF_ACCESS_AUD)
return {
email: payload.email,
name: payload.name
}
}Access Policies
Configure Access policies:
- Allow specific email domains
- Require MFA
- Set session duration
- Define group-based access
Email-Based Access Control
Roles
| Role | Permissions |
|---|---|
owner | Full access, can delete agent, manage admins |
admin | Full access, cannot delete agent |
viewer | Read-only access |
Managing Access
Add Admin
bash
curl -X POST https://your-domain.com/api/agents/{id}/admins \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"role": "admin"
}'Remove Admin
bash
curl -X DELETE https://your-domain.com/api/agents/{id}/admins/{adminId}List Admins
bash
curl https://your-domain.com/api/agents/{id}/adminsAccess Check Flow
┌─────────────────┐
│ Incoming │
│ Request │
└────────┬────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐
│ CF Access │────▶│ Extract Email │
│ JWT Present? │ Yes │ from JWT │
└────────┬────────┘ └────────┬────────┘
│ No │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Use Default │ │ Check Agent │
│ Access │ │ Access │
└────────┬────────┘ └────────┬────────┘
│ │
▼ ▼
┌─────────────────────────────────────────┐
│ Agent Access Check │
│ │
│ 1. Is agent 'default'? → Allow │
│ 2. Is user in agent_admins? → Allow │
│ 3. Otherwise → Deny │
└──────────────────────────────────────────┘Default Agent
The default agent has special behavior:
- Always accessible without authentication
- Cannot be deleted
- Used for initial setup
- Good for public/demo access
Auth Context
Frontend
Use the AuthContext:
tsx
import { useAuth } from '@/contexts/AuthContext'
function ProfilePage() {
const { user, isAuthenticated, logout } = useAuth()
if (!isAuthenticated) {
return <Navigate to="/login" />
}
return (
<div>
<p>Welcome, {user.email}</p>
<button onClick={logout}>Logout</button>
</div>
)
}Protected Routes
Wrap routes with ProtectedRoute:
tsx
<Route
path="/settings"
element={
<ProtectedRoute>
<SettingsPage />
</ProtectedRoute>
}
/>Backend
Check authentication in API routes:
typescript
export async function onRequestGet(context: EventContext<Env, string, any>) {
const { env, request, params } = context
// Get current user
const user = await getUser(request, env)
// Check agent access
const agentId = params.id
const hasAccess = await checkAgentAccess(env.DB, agentId, user?.email)
if (!hasAccess) {
return new Response('Forbidden', { status: 403 })
}
// Continue with request...
}Service Authentication
API Keys
Store API keys securely in agent settings:
json
{
"openai_api_key": "sk-...",
"anthropic_api_key": "sk-ant-...",
"telegram_bot_token": "123456:ABC..."
}Secure Storage
API keys are stored in the database:
- Encrypted at rest (D1 managed)
- Accessed only by the agent
- Never exposed in API responses
Using API Keys
typescript
// Retrieve from settings
const settings = await getAgentSettings(db, agentId)
const apiKey = settings.openai_api_key
// Use in service call
const response = await fetch('https://api.openai.com/v1/chat/completions', {
headers: {
'Authorization': `Bearer ${apiKey}`
}
})Security Best Practices
1. Enable Cloudflare Access
Use Cloudflare Access for production:
- SSO integration
- MFA enforcement
- Session management
- Audit logging
2. Principle of Least Privilege
Assign minimal permissions:
- Use
viewerrole for read-only users - Reserve
ownerfor trusted admins - Regular access reviews
3. Secure API Keys
Protect sensitive credentials:
- Never log API keys
- Rotate keys regularly
- Use environment-specific keys
4. Audit Access
Monitor authentication events:
- Track login attempts
- Review agent access changes
- Alert on suspicious activity
5. HTTPS Only
Always use HTTPS:
- Cloudflare provides automatic TLS
- Never expose HTTP endpoints
- Use secure WebSocket (wss://)
Troubleshooting
Access Denied Errors
- Check user email is in agent_admins
- Verify Cloudflare Access JWT is valid
- Confirm CF_ACCESS_AUD is correct
- Review Access policies
JWT Validation Failures
- Check token expiration
- Verify audience tag
- Confirm identity provider config
- Review Cloudflare Access logs
Role Issues
- Verify role in agent_admins table
- Check for duplicate entries
- Confirm role permissions