P
PUGUH

API Authentication

Learn how to authenticate with the ARSAKA PUGUH API.

Authentication Methods

PUGUH supports two authentication methods:

  1. API Keys: For server-to-server integrations (use X-API-Key header)
  2. JWT Tokens: For user-context operations (use Authorization: Bearer header)

API Keys

Obtaining an API Key

  1. Go to your profile settings
  2. Click "API Keys"
  3. Click "Create New Key"
  4. Copy the key (shown only once!)

Or create a service account for production use.

Using API Keys

Include the key in the X-API-Key header:

bash
curl -X GET https://api-puguh.arsaka.io/api/v1/organizations \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Organization-ID: YOUR_ORGANIZATION_ID"

Required Headers

HeaderRequiredDescription
X-API-Key Yes Your API key
X-Organization-ID Yes Your organization UUID
X-Application-ID Sometimes Required for application-scoped operations
Content-Type For POST/PUT Usually application/json

JWT Tokens

Login

Authenticate with email and password to get a JWT token pair:

bash
curl -X POST https://api-puguh.arsaka.io/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "your_password"
  }'

Response (returned directly, no wrapper):

json
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "dGhpcyBpcyBhIHJlZnJl..."
}

JWT tokens are signed with RS256 (asymmetric). You can verify tokens locally using the public key from the JWKS endpoint:

bash
curl -X GET https://api-puguh.arsaka.io/.well-known/jwks.json

Register

Create a new user account:

bash
curl -X POST https://api-puguh.arsaka.io/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newuser@example.com",
    "password": "secure_password",
    "full_name": "Jane Doe"
  }'

Response:

json
{
  "user_id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "newuser@example.com",
  "organization_id": "660e8400-e29b-41d4-a716-446655440000"
}

Using JWT Tokens

Include the access token in the Authorization header:

bash
curl -X GET https://api-puguh.arsaka.io/api/v1/organizations \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."

Refreshing Tokens

Before the access token expires, use the refresh token to get a new one:

bash
curl -X POST https://api-puguh.arsaka.io/api/v1/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "dGhpcyBpcyBhIHJlZnJl..."
  }'

Response:

json
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type": "Bearer",
  "expires_in": 3600
}

SDK Authentication

JavaScript / TypeScript

typescript
import { PuguhClient } from '@arsaka/puguh-sdk';

// Using API Key
const client = new PuguhClient({
  apiKey: process.env.PUGUH_API_KEY,
  organizationId: process.env.PUGUH_ORGANIZATION_ID,
});

// Using JWT
const client = new PuguhClient({
  accessToken: userToken,
  onTokenExpired: async () => {
    const newToken = await refreshToken();
    return newToken;
  },
});

Python

python
from puguh_sdk import PuguhClient

# Using API Key
client = PuguhClient(
    api_key=os.environ['PUGUH_API_KEY'],
    organization_id=os.environ['PUGUH_ORGANIZATION_ID']
)

# Using JWT
client = PuguhClient(
    access_token=user_token,
    on_token_expired=refresh_token_callback
)

Security Best Practices

API Key Security

  1. Never commit keys to source control
    bash
    # .gitignore
    .env
    *.key
  2. Use environment variables
    bash
    export PUGUH_API_KEY=your_key_here
  3. Rotate keys regularly
    • Rotate production keys quarterly
    • Rotate immediately if compromised
  4. Use separate keys per environment
    • Development key
    • Staging key
    • Production key

Token Security

  1. Store securely
    • Use secure cookies (HttpOnly, Secure, SameSite)
    • Don't store in localStorage for sensitive apps
  2. Short expiration
    • Access tokens: 1 hour recommended
    • Refresh tokens: 7-30 days
  3. Revoke on logout
    bash
    curl -X POST https://api-puguh.arsaka.io/api/v1/auth/logout \
      -H "Authorization: Bearer YOUR_TOKEN"

Error Responses

PUGUH uses standard HTTP status codes. Error responses follow the FastAPI format:

401 Unauthorized

Missing or invalid credentials:

json
{
  "detail": "Invalid or expired token"
}

403 Forbidden

Valid credentials but lacking permission:

json
{
  "detail": "Missing permission: organization.members.create"
}

422 Validation Error

Request body failed validation:

json
{
  "detail": [
    {
      "loc": ["body", "email"],
      "msg": "value is not a valid email address",
      "type": "value_error.email"
    }
  ]
}

429 Too Many Requests

json
{
  "detail": "Rate limit exceeded. Retry after 60 seconds."
}

Check the Retry-After header for the wait time in seconds.

Rate Limiting

API calls are rate limited per plan:

PlanRequests/minute
Free60
Pro300
Business1,000
EnterpriseCustom

Rate limit headers included in every response:

http
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1640000000
Retry-After: 60

Testing Authentication

Test API Key

Verify your API key works by calling the health endpoint:

bash
curl -X GET https://api-puguh.arsaka.io/api/v1/health \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-Organization-ID: YOUR_ORGANIZATION_ID"

Test JWT Token

Login and use the returned token to call a protected endpoint:

bash
# 1. Login to get a token
TOKEN=$(curl -s -X POST https://api-puguh.arsaka.io/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "password": "your_password"}' \
  | jq -r '.access_token')

# 2. Use the token
curl -X GET https://api-puguh.arsaka.io/api/v1/iam/users \
  -H "Authorization: Bearer $TOKEN"

OAuth Integration (Enterprise)

For SSO integration:

Authorization URL

http
https://api-puguh.arsaka.io/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=YOUR_REDIRECT_URI
  &response_type=code
  &scope=read:user read:resources
  &state=RANDOM_STATE

Exchange Code for Token

bash
curl -X POST https://api-puguh.arsaka.io/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=YOUR_REDIRECT_URI"

Related