Administrator Guide | Kamiwaza Docs

Documentation for Kamiwaza 0.8.0

This is documentation for Kamiwaza 0.8.0, which is no longer actively maintained. For the current GA release, see 1.0.1.

Version: 0.8.0

1. Authentication & Access Control

Kamiwaza provides enterprise-grade authentication built on Keycloak with OpenID Connect (OIDC) and JWT token validation.

1.1 Authentication Architecture

User → Keycloak (IdP) → JWT Token → Traefik → ForwardAuth → API Services

↓

[Validated] → Access Granted

↓

[Rejected] → 401/403 Error

Components:

1.2 Authentication Modes

Kamiwaza supports two operational modes:

Mode Use Case Configuration
With Authentication Production, staging, secure environments KAMIWAZA_USE_AUTH=true
Bypass Mode Local development, debugging KAMIWAZA_USE_AUTH=false

To enable authentication:

# In env.sh or environment

export KAMIWAZA_USE_AUTH=true

bash startup/kamiwazad.sh restart

Expected output:

Stopping kamiwazad ...

Starting kamiwazad ...

kamiwazad status: active (running)

⚠️ Warning: Bypass mode (KAMIWAZA_USE_AUTH=false) disables all authentication. Use only in secure development environments.

1.3 Token-Based Authentication

Kamiwaza uses RS256 JWT tokens with asymmetric cryptographic signatures.

Token Lifecycle:

  1. Acquisition: User authenticates with Keycloak via username/password or SSO
  2. Validation: ForwardAuth validates token signature against JWKS endpoint
  3. Authorization: User roles checked against RBAC policy
  4. Expiration: Access tokens expire (default: 1 hour), require refresh
  5. Revocation: Logout invalidates tokens

Token Delivery Methods:

2. User Management

2.1 Manage Local Users in the Console

The Settings → Auth & Users screen is the fastest way to create local accounts.

  1. Sign in to the Kamiwaza console with an administrator account.
  2. Open Settings in the left nav and switch to the Auth & Users tab.
  3. Click Add User.
  4. Fill in the modal:
    • Username – required login name.
    • Full Name / Email – optional but recommended for auditing.
    • Role – pick one of the built-in roles (viewer, user, admin). You can add multiple roles before saving.
    • Password – enter the initial password and disable the “Must change password” toggle if this account needs to log in programmatically.
  5. Click Save. The new user appears in the Local Users table.
  6. Use the pencil icon to edit roles later, the key icon to reset passwords, and the trash can to remove the user.

Why disable “Must change password”? ReBAC smoke tests and SDK logins need to authenticate immediately. Leaving the toggle enabled causes Keycloak to demand a password reset on first login, resulting in an “Invalid credentials” error for CLIs and service accounts.

2.2 Configure External Identity Providers

If your organization uses Google Workspace or another OIDC provider:

  1. In Settings → Auth & Users, switch to the Authentication Providers section.
  2. Choose Google or Generic OIDC.
  3. Supply the provider’s client ID, secret, and optional hosted domain.
  4. Click Register. The new provider shows up under Configured Providers immediately—no restart required.

2.4 User Roles and Permissions

Kamiwaza defines three primary roles:

Role Permissions Typical Users
admin Full access: read, write, delete, configure System administrators, platform operators
user Standard access: read, write (no delete/admin) Data scientists, developers, analysts
viewer Read-only access Auditors, observers, stakeholders

Assigning Roles:

  1. Navigate to Users → Select user
  2. Go to Role Mappings tab
  3. Under Realm Roles, select appropriate roles
  4. Click Add selected
  5. Changes take effect immediately (no logout required)

2.5 Password Policies

Configuring Password Requirements:

  1. Navigate to Realm SettingsSecurity DefensesPassword Policy
  2. Add policies:
    • Minimum Length: 12 characters (recommended)
    • Uppercase Characters: Require at least 1
    • Lowercase Characters: Require at least 1
    • Digits: Require at least 1
    • Special Characters: Require at least 1
    • Not Username: Prevent username as password
    • Password History: Prevent last 3 passwords
    • Expire Password: 90 days (recommended)

Password Reset Flow:

  1. User clicks "Forgot Password" on login page
  2. Keycloak sends password reset email
  3. User follows link and sets new password
  4. New password must meet policy requirements

2.6 Create a Local User in Lite Mode

Use this flow when KAMIWAZA_LITE=true and KAMIWAZA_USE_AUTH=false.

  1. Set the admin password (required)
export KAMIWAZA_LITE=true

export KAMIWAZA_USE_AUTH=false

# Provide a password or allow generation (written under $KAMIWAZA_ROOT/runtime)

export KAMIWAZA_ADMIN_PASSWORD="kamiwaza"  # any >=12 chars for non-community builds

# export KAMIWAZA_ALLOW_GENERATED_ADMIN_PASSWORD=true  # optional fallback
  1. Start services
bash launch.sh
  1. Mint an admin bearer token (direct to core on port 7777)
ADMIN_TOKEN=$(curl -sk -X POST http://localhost:7777/api/auth/token \
  -H 'content-type: application/x-www-form-urlencoded' \
  -d 'grant_type=password' \
  -d 'client_id=kamiwaza-platform' \
  -d "username=admin" \
  -d "password=${KAMIWAZA_ADMIN_PASSWORD}" | jq -r '.access_token')
  1. Create the user
curl -sk -X POST http://localhost:7777/api/auth/users/local \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "content-type: application/json" \
  -d '{"username":"demo","password":"demo12345678","email":"demo@example.com","roles":["user"]}' | jq
  1. Verify
curl -sk http://localhost:7777/api/auth/users -H "Authorization: Bearer ${ADMIN_TOKEN}" | jq

Troubleshooting:

3. Role-Based Access Control (RBAC)

3.1 RBAC Policy File

Access control is defined in YAML policy files that map endpoints to required roles.

Default Location:

ForwardAuth is stateless—set AUTH_GATEWAY_POLICY_FILE=$KAMIWAZA_ROOT/config/auth_gateway_policy.yaml (or the mounted path) so every restart reloads the same policy file.

Policy File Structure (default config/auth_gateway_policy.yaml):

version: 1

env: dev

default_deny: true

roles:

- id: admin

description: "Full system access"

- id: user

description: "Standard user access"

- id: viewer

description: "Read-only access"

- id: guest

description: "Minimal guest access"

endpoints:

# Health checks

- path: "/health"

methods: ["GET"]

roles: ["*"]

- path: "/api/health"

methods: ["GET"]

roles: ["*"]

# Auth endpoints (login/logout)

- path: "/auth/login"

methods: ["POST"]

roles: ["*"]

- path: "/auth/logout"

methods: ["POST"]

roles: ["*"]

# Who am I

- path: "/api/whoami"

methods: ["GET"]

roles: ["admin", "user", "viewer", "guest"]

# Models

- path: "/api/models*"

methods: ["GET"]

roles: ["admin", "user", "viewer"]

- path: "/api/models*"

methods: ["POST", "PUT", "DELETE"]

roles: ["admin", "user"]

# Serving deployments

- path: "/api/serving/deployments*"

methods: ["GET"]

roles: ["admin", "user", "viewer"]

- path: "/api/serving/deployments*"

methods: ["POST", "PUT", "DELETE"]

roles: ["admin", "user"]

# Admin-only APIs

- path: "/api/cluster*"

methods: ["*"]

roles: ["admin"]

- path: "/api/activity*"

methods: ["*"]

roles: ["admin"]

# Garden apps + tools

- path: "/api/apps*"

methods: ["GET"]

roles: ["admin", "user", "viewer"]

- path: "/api/apps*"

methods: ["POST", "PUT", "DELETE"]

roles: ["admin", "user"]

- path: "/api/tools*"

methods: ["GET"]

roles: ["admin", "user", "viewer"]

- path: "/api/tools*"

methods: ["POST", "PUT", "DELETE"]

roles: ["admin", "user"]

# Data Discovery Engine

- path: "/api/dde/status"

methods: ["GET"]

roles: ["viewer", "admin"]

- path: "/api/dde/search"

methods: ["POST"]

roles: ["viewer", "admin"]

- path: "/api/dde/reindex"

methods: ["POST"]

roles: ["admin"]

# Static assets

- path: "/static/*"

methods: ["GET"]

roles: ["admin", "user", "viewer", "guest"]

- path: "/assets/*"

methods: ["GET"]

roles: ["admin", "user", "viewer", "guest"]

- path: "/favicon.ico"

methods: ["GET"]

roles: ["admin", "user", "viewer", "guest"]

- path: "/manifest.json"

methods: ["GET"]

roles: ["admin", "user", "viewer", "guest"]

3.3 Path Matching Rules

Wildcard Patterns:

3.4 Adding Custom Endpoints

Example: Protecting a new analytics endpoint

endpoints:

# Add new analytics endpoint

- path: "/api/analytics/reports*"

methods: ["GET"]

roles: ["user", "admin"]

- path: "/api/analytics/reports*"

methods: ["POST", "DELETE"]

roles: ["admin"]

4. Identity Provider Integration

4.1 Keycloak Configuration

Realm:kamiwaza Client ID:kamiwaza-platform

Client Configuration Settings:

Setting Value Purpose
Access Type Public (SPA) or Confidential (backend) Authentication flow type
Valid Redirect URIs https://your-domain.com/* Allowed OAuth callback URLs
Web Origins https://your-domain.com CORS configuration
Direct Access Grants Enabled (dev), Disabled (prod) Password grant for testing

4.2 OAuth 2.0 / OpenID Connect Integration

Kamiwaza supports standard OIDC authentication flows.

Environment Configuration:

# Keycloak OIDC Settings

AUTH_GATEWAY_KEYCLOAK_URL=https://auth.yourdomain.com

AUTH_GATEWAY_KEYCLOAK_REALM=kamiwaza

AUTH_GATEWAY_KEYCLOAK_CLIENT_ID=kamiwaza-platform

# JWT Validation

AUTH_GATEWAY_JWT_ISSUER=https://auth.yourdomain.com/realms/kamiwaza

AUTH_GATEWAY_JWT_AUDIENCE=kamiwaza-platform

AUTH_GATEWAY_JWKS_URL=https://auth.yourdomain.com/realms/kamiwaza/protocol/openid-connect/certs

4.3 SAML Integration

Configure SAML Identity Provider in Keycloak:

  1. Navigate to Identity Providers in Keycloak admin console
  2. Select SAML v2.0
  3. Configure SAML settings:
    • Single Sign-On Service URL: Your IdP's SSO endpoint
    • Single Logout Service URL: Your IdP's logout endpoint
    • NameID Policy Format: urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
    • Principal Type: Subject NameID
  4. Upload IdP metadata XML or configure manually
  5. Map SAML attributes to Keycloak user attributes
  6. Enable identity provider in login flow

4.4 LDAP / Active Directory Integration

Configure LDAP Federation:

  1. Navigate to User FederationAdd providerldap
  2. Configure connection settings:
    • Connection URL: ldap://ldap.company.com:389 or ldaps:// for SSL
    • Bind DN: cn=admin,dc=company,dc=com
    • Bind Credential: LDAP admin password
  3. Configure LDAP search settings:
    • Users DN: ou=users,dc=company,dc=com
    • User Object Classes: inetOrgPerson, organizationalPerson
    • Username LDAP attribute: uid or sAMAccountName (AD)
    • RDN LDAP attribute: uid or cn
    • UUID LDAP attribute: entryUUID or objectGUID (AD)
  4. Save and test connection
  5. Synchronize users: Synchronize all users button

4.5 Single Sign-On (SSO) Setup

Google SSO Integration:

  1. Create OAuth 2.0 credentials in Google Cloud Console
  2. Configure authorized redirect URI:
https://auth.yourdomain.com/realms/kamiwaza/broker/google/endpoint
  1. In Keycloak, navigate to Identity ProvidersGoogle
  2. Enter Client ID and Client Secret from Google Console
  3. Save and enable

Testing SSO:

  1. Navigate to Kamiwaza login page
  2. Click SSO provider button (Google, Azure, etc.)
  3. Authenticate with external identity provider
  4. First-time users automatically create Keycloak account
  5. Subsequent logins use existing account

5. Security Configuration

5.1 JWT Token Configuration

Token Security Settings:

# JWT Validation (in env.sh)

AUTH_GATEWAY_JWT_AUDIENCE=kamiwaza-platform  # Required audience claim

AUTH_GATEWAY_JWT_ISSUER=https://auth.yourdomain.com/realms/kamiwaza

AUTH_GATEWAY_JWKS_URL=https://auth.yourdomain.com/realms/kamiwaza/protocol/openid-connect/certs

# Security Hardening

AUTH_REQUIRE_SUB=true  # Require 'sub' claim (user ID) in tokens

AUTH_EXPOSE_TOKEN_HEADER=false  # Don't expose tokens in response headers (production)

AUTH_ALLOW_UNSIGNED_STATE=false  # Require signed OIDC state parameter (production)

5.2 Session Management

Access Token Expiration:

Configure in Keycloak: Realm SettingsTokens

Best Practices:

5.4 Rate Limiting (Optional - Requires Redis)

Rate limiting requires Redis configuration:

# Redis connection for rate limiting

REDIS_HOST=localhost

REDIS_PORT=6379

REDIS_DB=0

Rate Limit Configuration:

# In auth_gateway_policy.yaml

rate_limits:

- path: "/api/models*"

requests_per_minute: 100

per_user: true

- path: "/api/auth/token"

requests_per_minute: 10

per_ip: true

6. Monitoring & Troubleshooting

6.1 Health Checks

Auth Service Health Endpoint:

curl http://localhost:7777/health

Response:

{

"status": "healthy",

"version": "1.0.0",

"uptime": 3600.5,

"KAMIWAZA_USE_AUTH": true,

"jwks_cache_status": "healthy"
}

Keycloak Health Check:

curl http://localhost:8080/health/ready

Response:

{"status":"UP"}

6.3 Common Issues and Solutions

Issue: 401 Unauthorized on All Requests

Symptoms: All API requests return 401 even with valid tokens

Troubleshooting:

  1. Check if auth is enabled:
echo $KAMIWAZA_USE_AUTH  # Should be 'true'
  1. Verify Keycloak is running:
docker ps | grep keycloak

curl http://localhost:8080/health/ready

Issue: 403 Forbidden (Valid Token)

Symptoms: Token is valid but access denied

Troubleshooting:

  1. Check user roles in token:
echo $TOKEN | cut -d. -f2 | base64 -d | jq .realm_access.roles
  1. Verify RBAC policy allows access:
cat $KAMIWAZA_ROOT/config/auth_gateway_policy.yaml
  1. Check policy file syntax:
# Invalid YAML prevents policy reload

yamllint $KAMIWAZA_ROOT/config/auth_gateway_policy.yaml

6.4 Diagnostic Commands

Test Token Generation:

# Get token from Keycloak

TOKEN=$(curl -s -X POST http://localhost:8080/realms/kamiwaza/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password" \
  -d "client_id=kamiwaza-platform" \
  -d "username=testuser" \
  -d "password=testpass" | jq -r .access_token)

# Decode token to inspect claims

echo $TOKEN | cut -d. -f2 | base64 -d | jq .

Verify Keycloak login flows

Use these checks after configuring SAML/OIDC to confirm the gateway and Keycloak agree on redirect URIs and credentials.

  1. OIDC loop
curl -I https://<gateway-host>/api/auth/login

Appendix A: Environment Variable Reference

Variable Description Default Required
KAMIWAZA_USE_AUTH Enable/disable authentication true No
AUTH_GATEWAY_JWT_ISSUER Expected JWT issuer URL - Yes
AUTH_GATEWAY_JWT_AUDIENCE Expected JWT audience claim - Recommended
AUTH_GATEWAY_JWKS_URL JWKS endpoint for key fetching - Yes
AUTH_GATEWAY_POLICY_FILE Path to RBAC policy file $KAMIWAZA_ROOT/config/auth_gateway_policy.yaml No

Appendix B: RBAC Policy Examples

Example 1: Tiered Access by Service

version: 1

env: production

default_deny: true

roles:

- id: admin

description: "System administrators"

- id: data_scientist

description: "Data scientists and ML engineers"

- id: analyst

description: "Business analysts and viewers"

endpoints:

# Model Management - Scientists can create/edit, analysts read-only

- path: "/api/models*"

methods: ["GET"]

roles: ["admin", "data_scientist", "analyst"]

- path: "/api/models*"

methods: ["POST", "PUT", "DELETE"]

roles: ["admin", "data_scientist"]

# Public endpoints

- path: "/health"

methods: ["GET"]

roles: ["*"]

Example 2: Read-Write Separation

version: 1

env: production

default_deny: true

roles:

- id: admin

- id: editor

- id: reader

endpoints:

# Read endpoints - All authenticated users

- path: "/api/models"

methods: ["GET"]

roles: ["admin", "editor", "reader"]

# Write endpoints - Editors and admins only

- path: "/api/models"

methods: ["POST", "PUT"]

roles: ["admin", "editor"]

# Delete endpoints - Admins only

- path: "/api/models*"

methods: ["DELETE"]

roles: ["admin"]