Skip to main content

SDK Authentication

Learn how to securely authenticate your applications with AxonFlow using OAuth2-style credentials and best practices for production deployments.

Overview

AxonFlow uses OAuth2-style Basic authentication for all deployments. Each organization uses a client ID (required) and client secret (optional for community mode) to authenticate API requests.

Authentication Header: Authorization: Basic base64(clientId:clientSecret)

Note: The client ID is recommended even for community/self-hosted deployments for request identification, metrics attribution, and audit logging. The client secret is only required for enterprise deployments.

Getting Your Credentials

For AWS Marketplace Deployments (In-VPC)

After deploying AxonFlow via AWS CloudFormation:

  1. Credentials are automatically generated during deployment
  2. Find them in AWS Secrets Manager at: axonflow/customers/{your-org-id}/credentials
  3. Or check CloudFormation stack outputs for ClientID and ClientSecret

Retrieve via AWS CLI:

aws secretsmanager get-secret-value \
--secret-id axonflow/customers/your-org-id/credentials \
--region eu-central-1 \
--query 'SecretString' \
--output text | jq .

For Direct Purchases

Contact AxonFlow sales to receive your organization's credentials:

  • Email: [email protected]
  • Subject: "Credentials Request - [Your Organization]"
  • Response Time: 1 business day

You'll receive credentials via secure channel (encrypted email or AWS Secrets Manager).

Using Credentials

TypeScript/JavaScript (SDK v2.3.0+):

import { AxonFlow } from '@axonflow/sdk';

const axonflow = new AxonFlow({
clientId: process.env.AXONFLOW_CLIENT_ID,
clientSecret: process.env.AXONFLOW_CLIENT_SECRET, // Optional for community mode
endpoint: process.env.AXONFLOW_ENDPOINT
});

Go (SDK v2.0.0+):

import (
"os"
"github.com/getaxonflow/axonflow-sdk-go/v2"
)

client, err := axonflow.NewClient(axonflow.AxonFlowConfig{
ClientID: os.Getenv("AXONFLOW_CLIENT_ID"),
ClientSecret: os.Getenv("AXONFLOW_CLIENT_SECRET"), // Optional for community mode
Endpoint: os.Getenv("AXONFLOW_ENDPOINT"),
})

Java (SDK v2.0.0+):

import com.getaxonflow.sdk.AxonFlow;
import com.getaxonflow.sdk.AxonFlowConfig;

AxonFlowConfig config = AxonFlowConfig.builder()
.clientId(System.getenv("AXONFLOW_CLIENT_ID"))
.clientSecret(System.getenv("AXONFLOW_CLIENT_SECRET")) // Optional for community mode
.endpoint(System.getenv("AXONFLOW_ENDPOINT"))
.build();

AxonFlow client = new AxonFlow(config);

Python (SDK v1.0.0+):

import os
from axonflow import AxonFlow

client = AxonFlow(
client_id=os.getenv("AXONFLOW_CLIENT_ID"),
client_secret=os.getenv("AXONFLOW_CLIENT_SECRET"), # Optional for community mode
endpoint=os.getenv("AXONFLOW_ENDPOINT")
)

Environment file (.env):

# OAuth2 Credentials (Current Method)
AXONFLOW_CLIENT_ID=your-org-id
AXONFLOW_CLIENT_SECRET=your-secret-key
AXONFLOW_ENDPOINT=https://YOUR_VPC_IP:8443

# Or for central deployments
AXONFLOW_CLIENT_ID=your-org-id
AXONFLOW_CLIENT_SECRET=your-secret-key
AXONFLOW_ENDPOINT=https://staging-eu.getaxonflow.com

For production In-VPC deployments, store credentials in AWS Secrets Manager:

TypeScript (AWS SDK v3):

import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
import { AxonFlow } from '@axonflow/sdk';

async function getAxonFlowClient() {
const secretsManager = new SecretsManagerClient({ region: 'eu-central-1' });

const response = await secretsManager.send(
new GetSecretValueCommand({
SecretId: 'axonflow/customers/your-org-id/credentials'
})
);

const credentials = JSON.parse(response.SecretString!);

return new AxonFlow({
clientId: credentials.client_id,
clientSecret: credentials.client_secret,
endpoint: 'https://YOUR_VPC_IP:8443'
});
}

const axonflow = await getAxonFlowClient();

Go:

import (
"encoding/json"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/getaxonflow/axonflow-sdk-go/v2"
)

type Credentials struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
}

func getAxonFlowClient() (*axonflow.Client, error) {
sess := session.Must(session.NewSession())
svc := secretsmanager.New(sess, aws.NewConfig().WithRegion("eu-central-1"))

result, err := svc.GetSecretValue(&secretsmanager.GetSecretValueInput{
SecretId: aws.String("axonflow/customers/your-org-id/credentials"),
})
if err != nil {
return nil, err
}

var creds Credentials
if err := json.Unmarshal([]byte(*result.SecretString), &creds); err != nil {
return nil, err
}

return axonflow.NewClient(axonflow.AxonFlowConfig{
ClientID: creds.ClientID,
ClientSecret: creds.ClientSecret,
Endpoint: "https://YOUR_VPC_IP:8443",
})
}

Security Best Practices

1. Never Hardcode Credentials

Bad:

const axonflow = new AxonFlow({
clientId: 'my-org-id', // Hardcoded!
clientSecret: 'secret-abc123' // Hardcoded!
});

Good:

const axonflow = new AxonFlow({
clientId: process.env.AXONFLOW_CLIENT_ID,
clientSecret: process.env.AXONFLOW_CLIENT_SECRET
});

2. Use Environment-Specific Credentials

Separate credentials for development, staging, and production:

# .env.development
AXONFLOW_CLIENT_ID=dev-org
AXONFLOW_CLIENT_SECRET=dev-secret

# .env.production
AXONFLOW_CLIENT_ID=prod-org
AXONFLOW_CLIENT_SECRET=prod-secret

3. Rotate Credentials Regularly

For production environments, rotate credentials every 90 days:

  1. Generate new credentials in AxonFlow dashboard
  2. Update environment variables/Secrets Manager
  3. Deploy updated configuration
  4. Revoke old credentials after 24 hours

4. Restrict Credential Permissions

In multi-tenant environments, use least-privilege credentials:

// Healthcare tenant only has access to healthcare policies
const healthcareAxonFlow = new AxonFlow({
clientId: process.env.HEALTHCARE_CLIENT_ID,
clientSecret: process.env.HEALTHCARE_CLIENT_SECRET,
tenant: 'healthcare'
});

// E-commerce tenant has separate access
const ecommerceAxonFlow = new AxonFlow({
clientId: process.env.ECOMMERCE_CLIENT_ID,
clientSecret: process.env.ECOMMERCE_CLIENT_SECRET,
tenant: 'ecommerce'
});

5. Never Expose Credentials Client-Side

Never do this in React/Vue/Angular:

// THIS IS INSECURE - Don't put credentials in frontend code!
const axonflow = new AxonFlow({
clientId: 'my-org', // Exposed in browser!
clientSecret: 'secret-abc123' // Exposed in browser!
});

Instead, use a backend proxy:

// Frontend - calls your backend
const response = await fetch('/api/ai-query', {
method: 'POST',
body: JSON.stringify({ prompt })
});

// Backend API route - has credentials
import { AxonFlow } from '@axonflow/sdk';

const axonflow = new AxonFlow({
clientId: process.env.AXONFLOW_CLIENT_ID, // Safe - server-side only
clientSecret: process.env.AXONFLOW_CLIENT_SECRET,
endpoint: process.env.AXONFLOW_ENDPOINT
});

export default async function handler(req, res) {
const { prompt, userToken } = req.body;

// Use Proxy Mode for simple governance
const result = await axonflow.executeQuery({
userToken: userToken || 'anonymous',
query: prompt,
requestType: 'chat'
});

res.json(result);
}

HTTP API Authentication

For direct HTTP API calls without an SDK, use Basic authentication:

# Create the Base64-encoded credentials
AUTH=$(echo -n 'your-client-id:your-client-secret' | base64)

# Make authenticated request
curl -X POST https://your-endpoint.com/api/v1/request \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: application/json" \
-d '{
"query": "What is 2+2?",
"request_type": "chat"
}'

For community mode (no client secret):

# Use just the client ID
AUTH=$(echo -n 'your-client-id:' | base64)

curl -X POST https://your-endpoint.com/api/v1/request \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: application/json" \
-d '{...}'

Multi-Tenant Authentication

For SaaS applications serving multiple tenants:

Tenant Isolation

import { AxonFlow } from '@axonflow/sdk';

// Initialize once per tenant
function getAxonFlowForTenant(tenantId: string) {
return new AxonFlow({
clientId: process.env.AXONFLOW_CLIENT_ID,
clientSecret: process.env.AXONFLOW_CLIENT_SECRET,
tenant: tenantId // Enforces tenant isolation
});
}

// Usage
const tenant1Client = getAxonFlowForTenant('healthcare-corp');
const tenant2Client = getAxonFlowForTenant('ecommerce-inc');

// Each client only sees their own policies and audit logs

Per-Tenant Credentials

For stricter isolation, use separate credentials per tenant:

// Database schema
{
tenant_id: 'healthcare-corp',
axonflow_client_id: 'healthcare-client',
axonflow_client_secret: 'healthcare-secret',
created_at: '2025-10-01'
}

// Retrieve from database
function getAxonFlowForTenant(tenantId: string) {
const tenant = db.tenants.findOne({ tenant_id: tenantId });

return new AxonFlow({
clientId: tenant.axonflow_client_id,
clientSecret: tenant.axonflow_client_secret,
tenant: tenantId
});
}

Common Authentication Issues

Issue 1: 401 Unauthorized

Cause: Invalid or missing credentials

Solution:

// Check credentials are set
console.log('Client ID:', process.env.AXONFLOW_CLIENT_ID?.substring(0, 10) + '...');

// Verify credentials are not empty
if (!process.env.AXONFLOW_CLIENT_ID) {
throw new Error('Missing AXONFLOW_CLIENT_ID');
}

Issue 2: 403 Forbidden

Cause: Credentials valid but lacks permissions

Solution:

  • Check tenant ID matches your credentials
  • Verify license tier supports requested features
  • Contact support to upgrade tier if needed

Issue 3: Connection Refused

Cause: Wrong endpoint URL

Solution:

For SaaS Mode:

const axonflow = new AxonFlow({
endpoint: 'https://staging-eu.getaxonflow.com' // Correct public endpoint
});

For In-VPC Mode:

const axonflow = new AxonFlow({
endpoint: 'https://YOUR_VPC_IP:8443' // VPC private endpoint (replace YOUR_VPC_IP)
});

Testing Authentication

Quick Test (cURL)

# Test public endpoint
curl -X POST https://staging-eu.getaxonflow.com/api/v1/request \
-H "Content-Type: application/json" \
-H "Authorization: Basic $(echo -n 'your-client-id:your-client-secret' | base64)" \
-d '{
"query": "What is 2+2?",
"request_type": "chat"
}'

# Expected: 200 OK with JSON response

Integration Test

TypeScript:

import { AxonFlow } from '@axonflow/sdk';

async function testAuthentication() {
const axonflow = new AxonFlow({
clientId: process.env.AXONFLOW_CLIENT_ID,
clientSecret: process.env.AXONFLOW_CLIENT_SECRET,
endpoint: process.env.AXONFLOW_ENDPOINT
});

try {
// Simple health check
const health = await axonflow.healthCheck();
console.log('Authentication successful');
return true;
} catch (error) {
console.error('Authentication failed:', error.message);
return false;
}
}

testAuthentication();

Go:

func testAuthentication() error {
client, err := axonflow.NewClient(axonflow.AxonFlowConfig{
Endpoint: os.Getenv("AXONFLOW_ENDPOINT"),
ClientID: os.Getenv("AXONFLOW_CLIENT_ID"),
ClientSecret: os.Getenv("AXONFLOW_CLIENT_SECRET"),
})
if err != nil {
return fmt.Errorf("failed to create client: %v", err)
}

err = client.HealthCheck()
if err != nil {
return fmt.Errorf("authentication failed: %v", err)
}

fmt.Println("Authentication successful")
return nil
}

Legacy Authentication (Deprecated)

Warning: The license key (X-License-Key header) authentication method is deprecated as of November 2025 and will be removed in a future release. All new deployments should use OAuth2 credentials (clientId/clientSecret).

What Changed

  • Old Method: License Key (X-License-Key header)
  • New Method: OAuth2 Basic Auth (Authorization: Basic base64(clientId:clientSecret))
  • Reason for Change: Industry-standard authentication, better security, simpler integration

Backward Compatibility

AxonFlow SDKs currently support both authentication methods for backward compatibility:

Legacy Code (Still Works but Deprecated):

// TypeScript - Old method (deprecated, use clientId/clientSecret instead)
const axonflow = new AxonFlow({
licenseKey: 'AXON-ENT-xxx-yyy', // deprecated
endpoint: 'https://...'
});
// Go - Old method (deprecated)
client, err := axonflow.NewClient(axonflow.AxonFlowConfig{
LicenseKey: "AXON-ENT-xxx-yyy", // deprecated
Endpoint: "https://...",
})

This backward compatibility will be maintained until June 2026 to give customers time to migrate.

Migrating from License Keys

Follow these steps to migrate your application:

Step 1: Obtain Your Credentials

Contact AxonFlow support to receive your organization's OAuth2 credentials:

  • Email: [email protected]
  • Subject: "OAuth2 Migration Request - [Your Organization]"
  • Include: Current License Key for verification

Step 2: Update Environment Variables

Replace your old credentials in .env:

# OLD (Remove these)
AXONFLOW_LICENSE_KEY=AXON-ENT-xxx-yyy

# NEW (Add these)
AXONFLOW_CLIENT_ID=your-org-id
AXONFLOW_CLIENT_SECRET=your-secret-key

Step 3: Update Code

TypeScript Migration:

// BEFORE (Deprecated licenseKey method)
import { AxonFlow } from '@axonflow/sdk';

const axonflow = new AxonFlow({
licenseKey: process.env.AXONFLOW_LICENSE_KEY, // deprecated
endpoint: process.env.AXONFLOW_ENDPOINT
});

// AFTER (Recommended OAuth2 method)
import { AxonFlow } from '@axonflow/sdk';

const axonflow = new AxonFlow({
clientId: process.env.AXONFLOW_CLIENT_ID,
clientSecret: process.env.AXONFLOW_CLIENT_SECRET,
endpoint: process.env.AXONFLOW_ENDPOINT
});

Go Migration:

// BEFORE (Old method)
import "github.com/getaxonflow/axonflow-sdk-go/v2"

client, err := axonflow.NewClient(axonflow.AxonFlowConfig{
LicenseKey: os.Getenv("AXONFLOW_LICENSE_KEY"), // deprecated
Endpoint: os.Getenv("AXONFLOW_ENDPOINT"),
})

// AFTER (New method)
import "github.com/getaxonflow/axonflow-sdk-go/v2"

client, err := axonflow.NewClient(axonflow.AxonFlowConfig{
ClientID: os.Getenv("AXONFLOW_CLIENT_ID"),
ClientSecret: os.Getenv("AXONFLOW_CLIENT_SECRET"),
Endpoint: os.Getenv("AXONFLOW_ENDPOINT"),
})

Step 4: Test Migration

Run your application with the new credentials:

# Set new environment variables
export AXONFLOW_CLIENT_ID=your-org-id
export AXONFLOW_CLIENT_SECRET=your-secret-key

# Remove old variable
unset AXONFLOW_LICENSE_KEY

# Run your app
npm start # or go run main.go

Step 5: Verify

Confirm authentication works with OAuth2:

curl -X GET https://YOUR_ENDPOINT/health \
-H "Authorization: Basic $(echo -n 'your-client-id:your-client-secret' | base64)"

# Expected: {"status":"healthy",...}

Migration Checklist

  • Contact support to receive OAuth2 credentials
  • Update environment variables (remove LICENSE_KEY, add CLIENT_ID/SECRET)
  • Update SDK initialization code
  • Test in development environment
  • Deploy to staging and verify
  • Deploy to production
  • Remove old environment variables from secrets manager
  • Update documentation and runbooks

Need Help Migrating?

Contact our migration support team:

  • Email: [email protected]
  • Slack: #oauth2-migration (priority support)
  • Response Time: < 4 hours during business hours

We can help with:

  • Credential generation
  • Code migration assistance
  • Testing and verification
  • Rollback procedures if needed

Next Steps

Support

Having authentication issues?

Include in your support request:

  • SDK version (TypeScript/Go/Java/Python)
  • Deployment mode (SaaS or In-VPC)
  • Error message and stack trace
  • Client ID (first 10 characters only, never share secret)