Skip to main content

Identities for AI Agents

AI agents require secure, managed identities to authenticate with Guardhouse and access protected resources. This guide covers creating and managing agent identities.

What is an AI Agent Identity?

An AI Agent Identity is a service account that represents your AI agent or autonomous system. Unlike user identities, agent identities:

  • No Human Interaction - No login screens or MFA challenges
  • Long-lived Sessions - Persistent authentication for long-running processes
  • Granular Permissions - Specific scopes for specific operations
  • Managed Lifecycle - Easy to rotate, disable, or revoke
  • Audit Trail - Complete visibility into agent activities
  • Multi-tenant Support - Use across multiple Guardhouse tenants

Use Cases

1. Autonomous AI Agents

# AI agent making API calls continuously
agent_client_id=ai_agent_client
agent_client_secret=agent_secret_token

# Agent authenticates as itself
curl -X POST https://your_tenant.guardhouse.cloud/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=$agent_client_id" \
-d "client_secret=$agent_client_secret" \
-d "audience=https://api.yourcompany.com"

# Agent uses access token for all API calls
curl -X GET https://api.yourcompany.com/data \
-H "Authorization: Bearer AGENT_ACCESS_TOKEN"

2. RAG (Retrieval-Augmented Generation) Systems

AI agents need to:

  • Read documents from your knowledge base
  • Access vector databases for semantic search
  • Make API calls to retrieve information
  • Generate responses based on retrieved context

3. Content Generation Agents

AI agents that:

  • Generate marketing copy, blog posts, or social media content
  • Create product descriptions or documentation
  • Automate content workflows
  • Access your APIs to generate content using your data

4. Data Processing Agents

Autonomous systems that:

  • Process large datasets
  • Perform data transformations
  • Run analytics or ML models
  • Integrate with multiple data sources

5. AI Assistant/Bot

Conversational AI that:

  • Interacts with users via chat interfaces
  • Answers customer service questions
  • Automates routine tasks
  • Accesses user data with proper authorization

Creating AI Agent Identities

Step 1: Create Client in Guardhouse Admin Console

  1. Navigate to Applications (Clients) section
  2. Click Create Application
  3. Choose Machine-to-Machine type
  4. Fill in details:
    • Name: My AI Agent - RAG System
    • Description: Agent for document retrieval and content generation
    • Type: Regular Web or Non-Interactive

Step 2: Configure Scopes

Assign appropriate scopes based on agent's purpose:

Agent TypeRecommended Scopes
Document Readerread:documents, read:files
Data Processorread:data, write:data
Content Generatorread:content, write:content
Customer Supportread:users, read:tickets
Analytics Agentread:analytics, read:reports

Step 3: Generate Client Credentials

Guardhouse provides:

  • Client ID: Unique identifier for your agent
  • Client Secret: Secret used for authentication
  • Client ID Example: agent_x7z9K3...
  • Client Secret Example: gsk_live_abc123xyz789...

Store these credentials securely in your environment or secret manager.

Step 4: Configure Access Token Lifetime

For long-running AI agents, configure:

  • Long-lived tokens - Extended expiration (e.g., 24 hours)
  • Automatic refresh - Handle token renewal seamlessly
  • Token rotation - Plan for secret rotation schedule

Authentication Pattern

Service-to-Service Authentication

┌─────────────────────────────────────────┐
│ AI Agent │
│ (Your Autonomous System) │
│ │
└────────────┬──────────────────────┘

│ Client Credentials Flow

┌─────────────────────────────────────────┐
│ Guardhouse API │
│ │
│ Validates Client ID & Secret │
│ Returns Access Token │
└────────────┬──────────────────────┘

│ Stores Token

┌─────────────────────────────────────────┐
│ Your API / Resources │
│ (Vector DB, Content API, etc.) │
│ │
└────────────┬──────────────────────┘

│ Verifies Agent Token

Implementing Agent Authentication

Node.js Example

const axios = require('axios');

class AIAgent {
constructor(clientId, clientSecret, audience) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.audience = audience;
this.accessToken = null;
this.tokenExpiresAt = null;
}

async authenticate() {
// Get access token using client credentials
const response = await axios.post(
'https://your_tenant.guardhouse.cloud/oauth/token',
new URLSearchParams({
grant_type: 'client_credentials',
client_id: this.clientId,
client_secret: this.clientSecret,
audience: this.audience
}),
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}
);

this.accessToken = response.data.access_token;
this.tokenExpiresAt = Date.now() + (response.data.expires_in * 1000);

return this.accessToken;
}

async callAPI(endpoint, options = {}) {
// Check if token needs refresh
if (Date.now() >= this.tokenExpiresAt) {
await this.authenticate();
}

// Make API call with agent token
const response = await axios.get(
`https://api.yourcompany.com${endpoint}`,
{
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
...options.headers
},
...options
}
);

return response.data;
}

async fetchDocument(id) {
// RAG agent fetching document
return await this.callAPI(`/documents/${id}`);
}

async generateResponse(prompt, context) {
// Call your LLM API with agent identity
return await axios.post(
'https://llm-api.yourcompany.com/generate',
{
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json'
},
data: {
model: 'gpt-4',
prompt: prompt,
context: context
}
}
);
}
}

// Usage
const agent = new AIAgent(
process.env.GUARDHOUSE_CLIENT_ID,
process.env.GUARDHOUSE_CLIENT_SECRET,
'https://api.yourcompany.com'
);

// Authenticate once
await agent.authenticate();

// Make multiple API calls
const doc = await agent.fetchDocument('/doc-123');
const response = await agent.generateResponse(
'Summarize this document',
{ document: doc.id, content: doc.content }
);

Python Example

import requests
import time
from datetime import datetime, timedelta

class AIAgent:
def __init__(self, client_id, client_secret, audience):
self.client_id = client_id
self.client_secret = client_secret
self.audience = audience
self.access_token = None
self.token_expires_at = None

def authenticate(self):
# Get access token using client credentials
response = requests.post(
'https://your_tenant.guardhouse.cloud/oauth/token',
data={
'grant_type': 'client_credentials',
'client_id': self.client_id,
'client_secret': self.client_secret,
'audience': self.audience
},
headers={
'Content-Type': 'application/x-www-form-urlencoded'
}
)

self.access_token = response.json()['access_token']
self.token_expires_at = datetime.utcnow() + timedelta(
seconds=response.json()['expires_in']
)

return self.access_token

def call_api(self, endpoint, **kwargs):
# Check if token needs refresh
if self.access_token and datetime.utcnow() >= self.token_expires_at:
self.authenticate()

# Make API call with agent token
headers = {
'Authorization': f'Bearer {self.access_token}',
'Content-Type': 'application/json',
**kwargs.get('headers', {})
}

response = requests.get(
f'https://api.yourcompany.com{endpoint}',
headers=headers,
**{k: v for k, v in kwargs.items() if k != 'headers'}
)

return response.json()

def fetch_document(self, doc_id):
# RAG agent fetching document
return self.call_api(f'/documents/{doc_id}')

def generate_response(self, prompt, context):
# Call your LLM API with agent identity
headers = {
'Authorization': f'Bearer {self.access_token}',
'Content-Type': 'application/json'
}

response = requests.post(
'https://llm-api.yourcompany.com/generate',
headers=headers,
json={
'model': 'gpt-4',
'prompt': prompt,
'context': context
}
)

return response.json()

# Usage
agent = AIAgent(
client_id=os.getenv('GUARDHOUSE_CLIENT_ID'),
client_secret=os.getenv('GUARDHOUSE_CLIENT_SECRET'),
audience='https://api.yourcompany.com'
)

# Authenticate once
agent.authenticate()

# Make multiple API calls
doc = agent.fetch_document('/doc-123')
response = agent.generate_response(
'Summarize this document',
{'document': doc['id'], 'content': doc['content']}
)

.NET Example

using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

public class AIAgent
{
private readonly HttpClient _httpClient;
private readonly string _clientId;
private readonly string _clientSecret;
private readonly string _audience;
private string _accessToken;
private DateTime _tokenExpiresAt;

public AIAgent(string clientId, string clientSecret, string audience)
{
_httpClient = new HttpClient();
_clientId = clientId;
_clientSecret = clientSecret;
_audience = audience;
}

public async Task AuthenticateAsync()
{
// Get access token using client credentials
var parameters = new Dictionary<string, string>
{
{ "grant_type", "client_credentials" },
{ "client_id", _clientId },
{ "client_secret", _clientSecret },
{ "audience", _audience }
};

var response = await _httpClient.PostAsync(
"https://your_tenant.guardhouse.cloud/oauth/token",
new FormUrlEncodedContent(parameters)
);

var data = await response.Content.ReadFromJsonAsync<JsonElement>();

_accessToken = data.GetProperty("access_token").GetString();
_tokenExpiresAt = DateTime.UtcNow.AddSeconds(
data.GetProperty("expires_in").GetInt32() - 600
);

_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _accessToken);

return _accessToken;
}

public async Task<T> CallApiAsync<T>(string endpoint, object options = null)
{
// Check if token needs refresh
if (_accessToken != null && DateTime.UtcNow >= _tokenExpiresAt)
{
await AuthenticateAsync();
}

var request = new HttpRequestMessage(HttpMethod.Get, endpoint);
request.Headers.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _accessToken);

var response = await _httpClient.SendAsync(request);

return await response.Content.ReadFromJsonAsync<T>();
}
}

// Usage
var agent = new AIAgent(
clientId: Environment.GetEnvironmentVariable("GUARDHOUSE_CLIENT_ID"),
clientSecret: Environment.GetEnvironmentVariable("GUARDHOUSE_CLIENT_SECRET"),
audience: "https://api.yourcompany.com"
);

// Authenticate once
await agent.AuthenticateAsync();

// Make multiple API calls
var doc = await agent.CallApiAsync<Document>("/documents/doc-123");

Best Practices for AI Agents

1. Security

  • Separate Credentials: Use unique client credentials per agent
  • Least Privilege: Give agents only required permissions
  • Token Rotation: Implement automatic secret rotation
  • Audit Logging: Log all agent actions for compliance
  • Rate Limiting: Implement proper backoff for API calls
  • Avoid: Hardcoding credentials, storing secrets in codebase

2. Performance

  • Token Caching: Cache tokens and refresh before expiration
  • Connection Pooling: Reuse HTTP connections
  • Parallel Requests: Process multiple operations concurrently
  • Batch Operations: Group API calls to reduce round trips
  • Error Handling: Implement retry logic with exponential backoff

3. Reliability

  • Health Checks: Monitor Guardhouse API health
  • Graceful Degradation: Handle partial failures gracefully
  • Fallback Mechanisms: Cache frequently accessed data
  • Monitoring: Track agent performance and uptime
  • Circuit Breakers: Prevent cascading failures

4. Observability

  • Structured Logging: Use consistent log formats
  • Metrics: Track token usage, API latency, error rates
  • Tracing: Implement distributed tracing for debugging
  • Alerting: Set up alerts for anomalies and failures
  • Dashboard: Create visibility into agent operations

Token Management Strategies

Long-lived Tokens

For continuous AI agents, request extended token lifetimes:

// Request longer-lived token (24 hours)
const response = await fetch('https://your_tenant.guardhouse.cloud/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
audience: 'https://api.yourcompany.com',
// Request longer lifetime
max_age: '86400' // 24 hours in seconds
})
});

Automatic Token Refresh

Implement token refresh before expiration:

class TokenManager {
constructor() {
this.token = null;
this.expiresAt = null;
this.refreshBuffer = 300000; // 5 minutes buffer
}

async getToken() {
// Check if token is still valid with buffer
if (this.token && Date.now() < (this.expiresAt - this.refreshBuffer)) {
return this.token;
}

// Refresh token
return await this.refreshToken();
}

async refreshToken() {
const response = await fetch('https://your_tenant.guardhouse.cloud/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
audience: 'https://api.yourcompany.com'
})
});

const data = await response.json();
this.token = data.access_token;
this.expiresAt = Date.now() + (data.expires_in * 1000);

return this.token;
}
}

Identity Management

Multiple Agents

For systems with multiple AI agents:

PatternDescriptionBenefits
Single IdentityAll agents use same identitySimpler, easier management
Per-Agent IdentityEach agent has own identityBetter isolation, individual permissions
HierarchicalGrouped by function/teamStructured permissions, auditability
DynamicIdentity created per sessionFlexibility, temporary access

Role-based Access

Implement role-based permissions for AI agents:

const AGENT_SCOPES = {
'read_only': ['read:documents', 'read:files'],
'writer': ['read:documents', 'write:documents'],
'editor': ['read:documents', 'write:documents', 'delete:documents'],
'admin': ['read:*', 'write:*', 'delete:*']
};

function hasPermission(agent, requiredScope) {
return agent.scopes.some(scope => requiredScope.includes(scope));
}

// Usage
const agent = { scopes: ['read:documents', 'write:documents'] };

if (hasPermission(agent, 'delete:documents')) {
console.log('Agent has deletion permission');
}

Troubleshooting

Common Issues

Issue: "Token expired before expected"

Cause: Agent token expired earlier than calculated Solution:

  • Implement automatic token refresh with buffer time
  • Monitor token expiration actively
  • Use health checks to validate token status

Issue: "Rate limited by Guardhouse"

Cause: Agent making too many requests Solution:

  • Implement exponential backoff
  • Add request queuing and throttling
  • Cache responses to reduce API calls

Issue: "Agent cannot access resources"

Cause: Missing or incorrect scopes Solution:

  • Verify scopes are granted to client in Guardhouse Admin Console
  • Check audience parameter matches your API
  • Ensure agent is not disabled or blocked

Support

For issues, questions, or contributions: