Authentication
Section titled โAuthenticationโThe Hoody API requires authentication for all operations. There are two authentication systems, each designed for different use cases.
After understanding what the Hoody API does (platform management), you need to understand how to authenticate to actually use it.
API Endpoints Summary
Section titled โAPI Endpoints SummaryโOfficial Technical Reference:
This Foundation page explains authentication concepts and best practices. For complete endpoint documentation:
User Authentication (JWT Tokens):
- POST /api/v1/users/auth/login - Login with username/password
- POST /api/v1/users/auth/refresh - Refresh access token
- GET /api/v1/users/auth/me - Get current user profile
- POST /api/v1/users/auth/logout - Invalidate session
Automation (Auth Tokens):
- POST /api/v1/auth/tokens - Create long-lived token
- GET /api/v1/auth/tokens - List all tokens
- GET /api/v1/auth/tokens/{id} - Get token details
- PUT /api/v1/auth/tokens/{id} - Update token configuration
- DELETE /api/v1/auth/tokens/{id} - Revoke token
Two Authentication Systems
Section titled โTwo Authentication SystemsโHoody provides two distinct authentication methods:
JWT Tokens (User Sessions)
Use for: Browser sessions, interactive work
POST /api/v1/users/auth/loginReturns:
token(access, 1 day)refreshToken(7 days)
Characteristics:
- โ Short-lived (secure)
- โ Refresh-able (no re-login)
- โ User-specific
- โ Not ideal for automation
Auth Tokens (Automation)
Use for: Scripts, AI agents, CI/CD, integrations
POST /api/v1/auth/tokensReturns:
hdy_...token (long-lived)
Characteristics:
- โ Long-lived (configurable)
- โ IP whitelist support
- โ Revocable anytime
- โ Per-token permissions
- โ Ideal for automation
Authentication Workflow
Section titled โAuthentication WorkflowโFor Interactive Use (Browser/CLI)
Section titled โFor Interactive Use (Browser/CLI)โStep 1: Login
# Login with email and password (or use --username instead of --email)hoody auth login --email you@example.com --password your_passwordimport { HoodyClient } from '@hoody-ai/hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.icu' });
// Login with credentials โ pass `email` OR `username` (not both required)const auth = await client.api.authentication.login({ email: 'you@example.com', password: 'your_password'});console.log(auth.data.token); // JWT access tokenconsole.log(auth.data.refreshToken); // Refresh token# Provide EITHER email OR username (only password is required)curl -X POST "https://api.hoody.icu/api/v1/users/auth/login" \ -H "Content-Type: application/json" \ -d '{"email": "you@example.com", "password": "your_password"}'# Alternative: -d '{"username": "your_username", "password": "your_password"}' Response:
{ "statusCode": 200, "message": "Login successful", "data": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": "63f8b0e5c9a1b2d3e4f5a6b7", "username": "your_username", "alias": "Your Display Name", "is_banned": false, "created_at": "2025-10-21T10:00:00.000Z", "updated_at": "2025-10-21T10:00:00.000Z" } }}Step 2: Use Access Token
# CLI stores the token automatically after loginhoody projects list// Pass token to client constructorconst client = new HoodyClient({ baseURL: 'https://api.hoody.icu', token: auth.data.token});const projects = await client.api.projects.list();# Include token in Authorization headercurl "https://api.hoody.icu/api/v1/projects" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."Step 3: Refresh When Expired
# CLI handles token refresh automatically# If your session expired, simply re-loginhoody auth login --username your_username --password your_password// Refresh the access tokenconst refreshed = await client.api.authentication.refreshToken({ refreshToken: auth.data.refreshToken});console.log(refreshed.data.token); // New access tokencurl -X POST "https://api.hoody.icu/api/v1/users/auth/refresh" \ -H "Content-Type: application/json" \ -d '{"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}' Returns: New access token + new refresh token (both rotated for security)
For Automation & AI (Recommended)
Section titled โFor Automation & AI (Recommended)โStep 1: Create Auth Token (one-time setup)
# Login firsthoody auth login --username your_username --password your_password
# Create a long-lived automation token with IP whitelisthoody auth create \ --alias "Production Automation Token" \ --ip-whitelist "203.0.113.10,203.0.113.20" \ --expires-at "2027-04-12T00:00:00Z"import { HoodyClient } from '@hoody-ai/hoody-sdk';
// Login first to get JWTconst client = new HoodyClient({ baseURL: 'https://api.hoody.icu' });const auth = await client.api.authentication.login({ username: 'your_username', password: 'your_password'});
// Create auth token using JWTconst jwtClient = new HoodyClient({ baseURL: 'https://api.hoody.icu', token: auth.data.token });const token = await jwtClient.api.authTokens.create({ alias: 'Production Automation Token', ip_whitelist: ['203.0.113.10', '203.0.113.20'], expires_at: '2027-04-12T00:00:00Z'});console.log(token.data.token); // hdy_... โ save this immediately!# Login to get JWTcurl -X POST "https://api.hoody.icu/api/v1/users/auth/login" \ -H "Content-Type: application/json" \ -d '{"username": "your_username", "password": "your_password"}'
# Create a long-lived automation tokencurl -X POST "https://api.hoody.icu/api/v1/auth/tokens" \ -H "Authorization: Bearer $JWT" \ -H "Content-Type: application/json" \ -d '{ "alias": "Production Automation Token", "ip_whitelist": ["203.0.113.10", "203.0.113.20"], "expires_at": "2027-04-12T00:00:00Z" }' Response:
{ "statusCode": 201, "message": "Auth token created successfully", "data": { "token": "hdy_abc123XyZ456...", "id": "63f8b0e5c9a1b2d3e4f5a6b7", "alias": "Production Automation Token", "prefix": "hdy_", "ip_whitelist": ["203.0.113.10", "203.0.113.20"], "expires_at": "2027-04-12T00:00:00.000Z", "is_enabled": true, "last_used_at": null, "last_used_ip": null, "created_at": "2025-11-09T15:00:00.000Z", "updated_at": "2025-11-09T15:00:00.000Z" }}Step 2: Use Auth Token (forever, until it expires or is revoked)
# Store token and use with CLIexport HOODY_TOKEN="hdy_abc123XyZ456..."
# All subsequent commands use this tokenhoody projects listhoody containers list// Use auth token in SDK clientconst client = new HoodyClient({ baseURL: 'https://api.hoody.icu', token: process.env.HOODY_TOKEN // hdy_abc123XyZ456...});
// All API calls are authenticatedconst projects = await client.api.projects.list();# Store in environment variable (never hardcode)export HOODY_TOKEN="hdy_abc123XyZ456..."
# Use in all API requestscurl "https://api.hoody.icu/api/v1/projects" \ -H "Authorization: Bearer $HOODY_TOKEN"Benefits:
- โ No credentials in code (secure)
- โ IP whitelist enforcement (restrict to specific IPs)
- โ Expiration control (ISO 8601 date, or never)
- โ Instant revocation (disable or delete token)
- โ Audit trail (last_used_at, last_used_ip)
Auth Token Management
Section titled โAuth Token ManagementโCreating Tokens with Security Features
Section titled โCreating Tokens with Security FeaturesโIP Whitelisting:
Multiple formats for expiration:
{ "expires_at": "2026-12-31T23:59:59Z"}{ "expires_at": 1735689599}{ "expires_at": null}Listing and Auditing Tokens
Section titled โListing and Auditing Tokensโ# List all your auth tokenshoody auth listconst tokens = await client.api.authTokens.list();tokens.data.forEach(t => { console.log(t.alias, t.is_enabled, t.last_used_at);});curl "https://api.hoody.icu/api/v1/auth/tokens" \ -H "Authorization: Bearer $HOODY_TOKEN" Response shows usage tracking:
{ "data": [ { "id": "63f8b0e5c9a1b2d3e4f5a6b7", "alias": "CI/CD Pipeline", "prefix": "hdy_", "ip_whitelist": ["203.0.113.50"], "expires_at": "2026-02-07T15:00:00.000Z", "is_enabled": true, "last_used_at": "2025-11-09T14:30:00.000Z", "last_used_ip": "203.0.113.50", "created_at": "2025-11-09T10:00:00.000Z", "updated_at": "2025-11-09T14:30:00.000Z" } ]}Audit your tokens:
- Check
last_used_atto identify unused tokens - Verify
last_used_ipmatches expected sources - Review
ip_whitelistrestrictions
Revoking Tokens
Section titled โRevoking TokensโDisable without deleting:
# Disable a token without deleting ithoody auth update $TOKEN_ID --enabled falseawait client.api.authTokens.update(tokenId, { is_enabled: false });curl -X PUT "https://api.hoody.icu/api/v1/auth/tokens/$TOKEN_ID" \ -H "Authorization: Bearer $HOODY_TOKEN" \ -H "Content-Type: application/json" \ -d '{"is_enabled": false}' Permanently delete:
# Permanently delete a tokenhoody auth delete $TOKEN_IDawait client.api.authTokens.delete(tokenId);curl -X DELETE "https://api.hoody.icu/api/v1/auth/tokens/$TOKEN_ID" \ -H "Authorization: Bearer $HOODY_TOKEN" Security Best Practices
Section titled โSecurity Best Practicesโ1. Never Hardcode Credentials
Section titled โ1. Never Hardcode Credentialsโ// NEVER do thisconst response = await fetch('https://api.hoody.icu/api/v1/projects', { headers: { 'Authorization': 'Bearer hdy_abc123hardcoded' }});// Use environment variablesconst response = await fetch('https://api.hoody.icu/api/v1/projects', { headers: { 'Authorization': `Bearer ${process.env.HOODY_TOKEN}` }});2. Use IP Whitelisting
Section titled โ2. Use IP WhitelistingโRestrict tokens to specific sources:
If token is leaked: It wonโt work from other IPs.
3. Set Expiration Appropriately
Section titled โ3. Set Expiration AppropriatelyโShort-lived for temporary access:
{ "alias": "Contractor Access", "expires_at": "2026-05-12T00:00:00Z"}Long-lived for permanent infrastructure:
{ "alias": "Production Services", "expires_at": "2027-04-12T00:00:00Z"}Review and rotate regularly.
4. Create Dedicated Tokens per Service
Section titled โ4. Create Dedicated Tokens per ServiceโDonโt share one token across multiple systems:
# Create separate tokensPOST /api/v1/auth/tokens { "alias": "GitHub Actions CI", ... }POST /api/v1/auth/tokens { "alias": "Monitoring System", ... }POST /api/v1/auth/tokens { "alias": "AI Agent Orchestrator", ... }If one service is compromised: Revoke only that token, others continue working.
For AI Agents
Section titled โFor AI AgentsโThe Auth Token system is designed for AI orchestration:
// AI agent configuration (environment variables)const HOODY_TOKEN = process.env.HOODY_TOKEN; // hdy_... tokenconst HOODY_API = 'https://api.hoody.icu';
// AI can now orchestrate infrastructureasync function aiAgentWorkflow(task) { const headers = { 'Authorization': `Bearer ${HOODY_TOKEN}`, 'Content-Type': 'application/json' };
// AI decides: "Need a container to process this task" const container = await fetch(`${HOODY_API}/api/v1/projects/${projectId}/containers`, { method: 'POST', headers, body: JSON.stringify({ name: `ai-task-${Date.now()}`, server_id: 'your-server-id', hoody_kit: true }) }).then(r => r.json());
// Wait for container to be running await waitForStatus(container.data.id, 'running');
// Get container URLs and use them const terminalUrl = `https://${projectId}-${container.data.id}-terminal-1.${container.data.server_name}.containers.hoody.icu`;
// AI executes commands in the new container await fetch(`${terminalUrl}/execute`, { method: 'POST', body: JSON.stringify({ command: task.command }) });
// AI snapshots when done await fetch(`${HOODY_API}/api/v1/containers/${container.data.id}/snapshots`, { method: 'POST', headers, body: JSON.stringify({ alias: `task-${task.id}` }) });
return container;}The AI only needs:
- A Hoody Auth Token (environment variable)
- Understanding of HTTP (it already has this)
No SDK. No training. Just HTTP.
Token Comparison
Section titled โToken Comparisonโ| Feature | JWT (Login) | Auth Token (hdy_โฆ) |
|---|---|---|
| Lifetime | 1 day (access) 7 days (refresh) | Configurable (ISO 8601 date, โtodayโ, โtomorrowโ, or forever) |
| Use Case | User sessions | Automation, AI, scripts |
| Refresh | Yes (via refresh token) | No (create new when expired) |
| IP Whitelist | No | Yes (optional) |
| Revocation | Logout endpoint | Delete or disable |
| Visibility | Managed by browser | One-time show during creation |
| Security | Short-lived = more secure | Long-lived but IP-restricted |
Complete Authentication Examples
Section titled โComplete Authentication ExamplesโExample 1: User Login Flow
Section titled โExample 1: User Login Flowโ# 1. Logincurl -X POST "https://api.hoody.icu/api/v1/users/auth/login" \ -H "Content-Type: application/json" \ -d '{ "username": "dev_user", "password": "strong_password_here" }'
# Response includes tokens# {# "data": {# "token": "eyJhbG...",# "refreshToken": "eyJhbG...",# "user": { ... }# }# }
# 2. Use access token (valid 1 day)curl "https://api.hoody.icu/api/v1/projects" \ -H "Authorization: Bearer eyJhbG..."
# 3. Refresh before expiration (within 7 days)curl -X POST "https://api.hoody.icu/api/v1/users/auth/refresh" \ -H "Content-Type: application/json" \ -d '{"refreshToken": "eyJhbG..."}'
# 4. Logout (optional, invalidates session)curl -X POST "https://api.hoody.icu/api/v1/users/auth/logout" \ -H "Authorization: Bearer eyJhbG..."Example 2: Create Automation Token
Section titled โExample 2: Create Automation Tokenโ# 1. Login to get JWTcurl -X POST "https://api.hoody.icu/api/v1/users/auth/login" \ -d '{"username": "your_username", "password": "your_password"}' \ > login.json
# Extract JWTJWT=$(cat login.json | jq -r '.data.token')
# 2. Create auth token for CI/CDcurl -X POST "https://api.hoody.icu/api/v1/auth/tokens" \ -H "Authorization: Bearer $JWT" \ -H "Content-Type: application/json" \ -d '{ "alias": "GitHub Actions Deployment", "ip_whitelist": ["140.82.112.0/20"], "expires_at": "2027-04-12T00:00:00Z" }' > token.json
# Extract auth tokenAUTH_TOKEN=$(cat token.json | jq -r '.data.token')
# 3. Save to GitHub Secrets as HOODY_TOKENecho "HOODY_TOKEN=$AUTH_TOKEN"
# 4. Use in GitHub Actions workflow# - name: Deploy via Hoody API# env:# HOODY_TOKEN: ${{ secrets.HOODY_TOKEN }}# run: |# curl "https://api.hoody.icu/api/v1/containers/$CONTAINER_ID/start" \# -H "Authorization: Bearer $HOODY_TOKEN"Example 3: AI Agent Setup
Section titled โExample 3: AI Agent Setupโ// AI agent configuration fileHOODY_TOKEN=hdy_abc123def456...HOODY_PROJECT_ID=63f8b0e5c9a1b2d3e4f5a6b7
// agent.jsimport 'dotenv/config';
class HoodyAgent { constructor() { this.token = process.env.HOODY_TOKEN; this.projectId = process.env.HOODY_PROJECT_ID; this.api = 'https://api.hoody.icu'; }
async callAPI(endpoint, options = {}) { return fetch(`${this.api}${endpoint}`, { ...options, headers: { 'Authorization': `Bearer ${this.token}`, 'Content-Type': 'application/json', ...options.headers } }); }
async spawnContainer(name, config) { const response = await this.callAPI( `/api/v1/projects/${this.projectId}/containers`, { method: 'POST', body: JSON.stringify({ name, server_id: config.serverId, hoody_kit: true, ...config }) } ); return response.json(); }
async executeInContainer(containerId, command) { // First get container details to construct service URL const container = await this.callAPI(`/api/v1/containers/${containerId}`) .then(r => r.json());
// Construct terminal URL const terminalUrl = `https://${this.projectId}-${containerId}-terminal-1.${container.data.server_name}.containers.hoody.icu`;
// Execute command (no auth needed if container permissions are open) return fetch(`${terminalUrl}/execute`, { method: 'POST', body: JSON.stringify({ command }) }); }}
// AI uses this class for ALL Hoody operationsconst agent = new HoodyAgent();await agent.spawnContainer('ai-workspace', { serverId: 'server-123' });The AI only needs environment variables. No password handling. No credential management.
Managing Tokens
Section titled โManaging TokensโList All Tokens
Section titled โList All Tokensโ Update Token Configuration
Section titled โUpdate Token ConfigurationโChange IP whitelist:
Extend expiration:
Temporarily disable:
Token Rotation Strategy
Section titled โToken Rotation StrategyโBest practice for production:
# 1. Create new tokenNEW_TOKEN=$(curl -X POST "https://api.hoody.icu/api/v1/auth/tokens" \ -H "Authorization: Bearer YOUR_JWT" \ -d '{"alias": "Production V2", "expires_at": "2027-04-12T00:00:00Z"}' \ | jq -r '.data.token')
# 2. Update your services with new token# (Deploy new environment variable to all services)
# 3. Wait 24-48 hours for old token usage to drop
# 4. Check old token is unusedcurl "https://api.hoody.icu/api/v1/auth/tokens/{old_token_id}" \ -H "Authorization: Bearer YOUR_JWT" \ | jq '.data.last_used_at'
# 5. Delete old tokencurl -X DELETE "https://api.hoody.icu/api/v1/auth/tokens/{old_token_id}" \ -H "Authorization: Bearer YOUR_JWT"Common Patterns
Section titled โCommon PatternsโPattern 1: Short-Lived Scripts
Section titled โPattern 1: Short-Lived ScriptsโFor one-time operations:
Use the token for your migration, and it will auto-expire tomorrow.
Pattern 2: Per-Environment Tokens
Section titled โPattern 2: Per-Environment TokensโDifferent tokens for different environments:
Development token (permissive):
Staging token (IP-restricted):
Production token (strict):
Pattern 3: Emergency Revocation
Section titled โPattern 3: Emergency RevocationโIf a token is compromised:
1. Immediately disable:
2. Create replacement with different IP whitelist:
3. Update services, then delete old token:
Useful Questions
Section titled โUseful QuestionsโShould I use JWT tokens or Auth Tokens for my scripts?
Section titled โShould I use JWT tokens or Auth Tokens for my scripts?โAlways use Auth Tokens (hdy_...) for scripts and automation. JWTs from login are designed for short-lived user sessions and expire after 1 day. Auth Tokens can live for years with IP whitelisting and revocation support.
Can I create an Auth Token using another Auth Token?
Section titled โCan I create an Auth Token using another Auth Token?โNo. You must use a JWT from user login to create Auth Tokens. This prevents token proliferationโif an Auth Token is compromised, it canโt create more tokens. Always keep one user account secure for Auth Token management.
How do I share API access with my team without sharing passwords?
Section titled โHow do I share API access with my team without sharing passwords?โCreate individual Auth Tokens for each team member with specific IP whitelists. Each person gets their own hdy_... token, and you can revoke any token independently if someone leaves the team.
What happens when my JWT access token expires?
Section titled โWhat happens when my JWT access token expires?โAfter 1 day, the access token expires. Use your refresh token (valid 7 days) to get a new access token via POST /api/v1/users/auth/refresh. If the refresh token also expires, you must login again with username/password.
Can I use the same Auth Token across multiple servers or applications?
Section titled โCan I use the same Auth Token across multiple servers or applications?โYes, but treat that as convenience, not best practice. A single token can work across multiple projects/servers, yet isolation is stronger with separate tokens per app/environment.
For realm-restricted tokens:
- If
realm_idsis non-empty (orallow_no_realm: false), use realm-scoped hosts likehttps://{realmId}.api.hoody.icu. - Use
GET /api/v1/auth/tokens/meonhttps://api.hoody.icuto discover allowed realms before selecting a realm host.
How secure are Auth Tokens with no IP whitelist?
Section titled โHow secure are Auth Tokens with no IP whitelist?โWithout IP whitelist, a leaked token can be used from anywhere. While the token itself is cryptographically strong (60+ character random string), IP whitelisting adds defense-in-depth. Use it for production tokens, skip it for low-sensitivity automation.
Can Auth Tokens expire while my script is running?
Section titled โCan Auth Tokens expire while my script is running?โYes. If a long-running script spans the expiration time, it will start getting 401 errors. For long processes, use generous expiration (a far-future ISO 8601 date or null) or implement token refresh logic that creates a new token before the old one expires.
Whatโs the difference between disabling and deleting an Auth Token?
Section titled โWhatโs the difference between disabling and deleting an Auth Token?โDisable sets is_enabled: falseโtoken stops working but you can re-enable it later with the same ID. Delete permanently removes the tokenโcannot be recovered. Use disable for temporary suspension, delete for permanent revocation.
Can I use Auth Tokens with realm-scoped APIs?
Section titled โCan I use Auth Tokens with realm-scoped APIs?โYes. Auth Tokens work with realm-scoped APIs ({realmId}.api.hoody.icu), and unrestricted tokens can also use the base API host.
Important behavior:
- Tokens with non-empty
realm_idsare restricted to those realm IDs. - Tokens with
allow_no_realm: falsecannot use base host for resource operations. - Realm-restricted tokens can still call
GET /api/v1/auth/tokens/meon base host to bootstrap realm discovery.
How do I rotate Auth Tokens for zero-downtime updates?
Section titled โHow do I rotate Auth Tokens for zero-downtime updates?โCreate the new token, deploy it to your services, verify the new token works, wait 24-48 hours, check old tokenโs last_used_at is old, then delete the old token. Both tokens work simultaneously during the transition.
Troubleshooting
Section titled โTroubleshootingโLogin Fails (Invalid Credentials)
Section titled โLogin Fails (Invalid Credentials)โProblem: Login returns 401 with โInvalid credentialsโ
Solutions:
- Verify username/password:
- Check account status:
- Account might be banned (
is_banned: true) - Contact support if legitimate user
- Account might be banned (
JWT Token Expired
Section titled โJWT Token ExpiredโProblem: Requests return 401 after some time
Cause: Access token expires after 1 day
Solution - Use refresh token:
Returns new access token + new refresh token.
Refresh token expired? (after 7 days) - Login again
Auth Token Not Working
Section titled โAuth Token Not WorkingโProblem: hdy_... token returns 403 Forbidden
Check IP whitelist:
Compare the ip_whitelist array with your current IP (run curl https://ifconfig.me in terminal).
Solution - Update whitelist:
Token Creation Returns 401
Section titled โToken Creation Returns 401โProblem: Canโt create Auth Token, getting 401
Cause: Youโre using an Auth Token to create another Auth Token
Solution: Use a JWT from login instead:
# 1. Login firstcurl -X POST "https://api.hoody.icu/api/v1/users/auth/login" \ -d '{"username": "your_username", "password": "your_password"}' \ > login.json
# 2. Extract JWTJWT=$(cat login.json | jq -r '.data.token')
# 3. Create Auth Token with JWTcurl -X POST "https://api.hoody.icu/api/v1/auth/tokens" \ -H "Authorization: Bearer $JWT" \ -d '{"alias": "My Token", "expires_at": "2027-04-12T00:00:00Z"}'Lost Auth Token Value
Section titled โLost Auth Token ValueโProblem: Created token but didnโt save the hdy_... value
Reality: Cannot retrieve token value after creation
Solution:
- Disable the old token:
- Create new token:
Automation Breaking Randomly
Section titled โAutomation Breaking RandomlyโProblem: Scripts work sometimes, fail other times with 403
Likely cause: IP whitelist + dynamic IP
Check if your IP changed:
Run curl https://ifconfig.me in terminal to get your current IP, then compare with token whitelist:
Solutions:
-
Use CIDR range instead of single IP: Instead of
"203.0.113.50/32", use"203.0.113.0/24"(allows entire subnet) -
Remove IP whitelist for non-sensitive automation:
- Use static IP for automation servers
Whatโs Next
Section titled โWhatโs NextโNow that you can authenticate:
- Create Projects - Organize your containers
- Spawn Containers - Create your first HTTP computer
- Configure Networking - Set up routing and firewall
- Create Proxy Aliases - Get clean URLs for production
Everything starts with authentication. Everything else is HTTP.
User sessions use JWTs.
Automation uses Auth Tokens.
Never hardcode credentials.
Use environment variables. Use IP whitelists. Use expiration.
This is how you securely control infinite computers.