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
- Navigate to Applications (Clients) section
- Click Create Application
- Choose Machine-to-Machine type
- Fill in details:
- Name:
My AI Agent - RAG System - Description:
Agent for document retrieval and content generation - Type:
Regular WeborNon-Interactive
- Name:
Step 2: Configure Scopes
Assign appropriate scopes based on agent's purpose:
| Agent Type | Recommended Scopes |
|---|---|
| Document Reader | read:documents, read:files |
| Data Processor | read:data, write:data |
| Content Generator | read:content, write:content |
| Customer Support | read:users, read:tickets |
| Analytics Agent | read: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:
| Pattern | Description | Benefits |
|---|---|---|
| Single Identity | All agents use same identity | Simpler, easier management |
| Per-Agent Identity | Each agent has own identity | Better isolation, individual permissions |
| Hierarchical | Grouped by function/team | Structured permissions, auditability |
| Dynamic | Identity created per session | Flexibility, 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
Related Documentation
- Client Credentials Flow - M2M authentication details
- Rate Limiting - Managing request limits
- Introspection for AI Requests - Token validation methods
- User API - Managing agent identities via API
Support
For issues, questions, or contributions: