Organization and User Management
Overview
The Agent Passport Registry supports multi-tenant architecture with organizations and users. This system allows for proper ownership, access control, and assurance verification across different entities.
Core Concepts
Organizations
- Multi-tenant entities that can own multiple agent passports
- Member management with role-based access control
- Assurance levels that apply to all owned passports
- Domain verification for enhanced trust
Users
- Individual entities that can own agent passports
- Assurance verification through various methods
- Organization membership for collaborative management
Ownership Model
- Passports belong to owners (organizations or users)
- Inherited assurance levels from owner to passport
- Role-based permissions for organization members
- Verifiable Attestation for all ownership changes
API Endpoints
Organizations
Create Organization
POST /api/orgs
Content-Type: application/json
{
"name": "Acme Corporation",
"domain": "acme.com",
"contact_email": "[email protected]"
}
Response:
{
"org_id": "ap_org_12345678",
"name": "Acme Corporation",
"domain": "acme.com",
"contact_email": "[email protected]",
"members": [],
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"assurance_level": "L0"
}
Get Organization Members
GET /api/orgs/{org_id}/members
Response:
{
"org_id": "ap_org_12345678",
"name": "Acme Corporation",
"members": [
{
"user_id": "ap_user_87654321",
"role": "admin",
"added_at": "2024-01-15T10:30:00Z"
},
{
"user_id": "ap_user_11111111",
"role": "member",
"added_at": "2024-01-16T09:15:00Z"
}
]
}
Add Organization Member
POST /api/orgs/{org_id}/members
Content-Type: application/json
{
"user_id": "ap_user_87654321",
"role": "admin"
}
Users
Create User
POST /api/users
Content-Type: application/json
{
"email": "[email protected]",
"display_name": "John Doe"
}
Response:
{
"user_id": "ap_user_87654321",
"email": "[email protected]",
"display_name": "John Doe",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"assurance_level": "L0"
}
Owner Passports
Get Owner's Passports
GET /api/owners/{owner_id}/passports
Response:
{
"owner_id": "ap_org_12345678",
"owner_type": "org",
"owner_display": "Acme Corporation",
"passports": [
{
"agent_id": "ap_a2d10232c6534523812423eec8a1425c45678",
"name": "Customer Support AI",
"status": "active",
"created_at": "2024-01-15T10:30:00Z"
}
]
}
Assurance Levels
Level Definitions
| Level | Name | Description | Verification Method |
|---|---|---|---|
| L0 | Self | Self-declared | None |
| L1 | Email verification | Email confirmation | |
| L2 | GitHub | GitHub account verification | OAuth |
| L3 | Domain | Domain ownership verification | DNS/SSL |
| L4KYC | KYC | Know Your Customer | Identity verification |
| L4FIN | Financial | Financial institution verification | Banking data |
Assurance Inheritance
Passports inherit assurance levels from their owners:
// Organization with L2 assurance
const org = {
org_id: "ap_org_12345678",
assurance_level: "L2",
assurance_method: "github"
};
// All passports owned by this org inherit L2 assurance
const passport = {
agent_id: "ap_a2d10232c6534523812423eec8a1425c45678",
owner_id: "ap_org_12345678",
assurance_level: "L2", // Inherited from org
assurance_method: "github"
};
Implementation Examples
Creating an Organization with Members
import { AgentPassportClient } from '@agent-passport/sdk';
const client = new AgentPassportClient({
baseUrl: 'https://api.aport.io',
adminToken: process.env.ADMIN_TOKEN
});
// 1. Create organization
const org = await client.createOrganization({
name: 'Acme Corporation',
domain: 'acme.com',
contact_email: '[email protected]'
});
// 2. Create users
const admin = await client.createUser({
email: '[email protected]',
display_name: 'Admin User'
});
const member = await client.createUser({
email: '[email protected]',
display_name: 'Member User'
});
// 3. Add members to organization
await client.addOrgMember(org.org_id, {
user_id: admin.user_id,
role: 'admin'
});
await client.addOrgMember(org.org_id, {
user_id: member.user_id,
role: 'member'
});
// 4. Create passport owned by organization
const passport = await client.createPassport({
name: 'Customer Support AI',
owner_id: org.org_id,
controller_type: 'org',
role: 'Customer Support Agent',
description: 'AI agent for customer support',
capabilities: [
{ id: 'messaging.send' },
{ id: 'crm.update' }
],
limits: {
max_actions_per_min: 100,
allow_pii: false
},
regions: ['US-CA', 'US-NY'],
status: 'active',
contact: '[email protected]'
});
Checking Ownership and Permissions
// Verify agent and check ownership
const passport = await client.verifyAgent('ap_a2d10232c6534523812423eec8a1425c45678');
if (passport.owner_type === 'org') {
console.log(`Agent owned by organization: ${passport.owner_display}`);
// Check if user is member of owning organization
const orgMembers = await client.getOrgMembers(passport.owner_id);
const isMember = orgMembers.members.some(
member => member.user_id === currentUserId
);
if (!isMember) {
throw new Error('User is not a member of the owning organization');
}
}
Assurance Level Validation
// Check if agent meets required assurance level
function validateAssuranceLevel(passport: PassportData, requiredLevel: string) {
const levelHierarchy = ['L0', 'L1', 'L2', 'L3', 'L4KYC', 'L4FIN'];
const currentLevelIndex = levelHierarchy.indexOf(passport.assurance_level);
const requiredLevelIndex = levelHierarchy.indexOf(requiredLevel);
if (currentLevelIndex < requiredLevelIndex) {
throw new Error(
`Agent assurance level ${passport.assurance_level} is insufficient. Required: ${requiredLevel}`
);
}
}
// Usage
const passport = await client.verifyAgent('ap_a2d10232c6534523812423eec8a1425c45678');
validateAssuranceLevel(passport, 'L2'); // Requires L2 or higher
Role-Based Access Control
Organization Roles
| Role | Permissions |
|---|---|
| admin | Create/update/delete passports, manage members, view all data |
| member | View passports, limited update permissions |
Permission Checking
// Check if user can perform action on passport
async function checkPermission(
userId: string,
passportId: string,
action: string
): Promise<boolean> {
const passport = await client.verifyAgent(passportId);
// Check if user owns the passport directly
if (passport.owner_type === 'user' && passport.owner_id === userId) {
return true;
}
// Check if user is admin of owning organization
if (passport.owner_type === 'org') {
const orgMembers = await client.getOrgMembers(passport.owner_id);
const userMember = orgMembers.members.find(
member => member.user_id === userId
);
if (userMember?.role === 'admin') {
return true;
}
}
return false;
}
// Usage
const canUpdate = await checkPermission(userId, passportId, 'update');
if (!canUpdate) {
throw new Error('Insufficient permissions to update passport');
}
Domain Verification
Setting Up Domain Verification
// 1. Create organization with domain
const org = await client.createOrganization({
name: 'Acme Corporation',
domain: 'acme.com',
contact_email: '[email protected]'
});
// 2. Organization admin adds DNS record
// TXT record: agent-passport-verification=ap_org_12345678
// 3. Verify domain ownership
const verification = await client.verifyDomain(org.org_id);
if (verification.verified) {
// Update organization assurance level
await client.updateOrganization(org.org_id, {
assurance_level: 'L3',
assurance_method: 'domain',
assurance_verified_at: new Date().toISOString()
});
}
Audit and Compliance
Ownership Changes
All ownership changes are logged:
{
"event": "passport_ownership_changed",
"timestamp": "2024-01-15T10:30:00Z",
"passport_id": "ap_a2d10232c6534523812423eec8a1425c45678",
"previous_owner": "ap_user_11111111",
"new_owner": "ap_org_12345678",
"changed_by": "ap_user_87654321",
"reason": "Organization acquisition"
}
Member Management
Organization membership changes are tracked:
{
"event": "org_member_added",
"timestamp": "2024-01-15T10:30:00Z",
"org_id": "ap_org_12345678",
"user_id": "ap_user_87654321",
"role": "admin",
"added_by": "ap_user_11111111"
}
Best Practices
1. Organization Structure
- Use organizations for business entities
- Use users for individual developers
- Assign appropriate roles based on responsibilities
- Regularly audit membership and remove inactive users
2. Assurance Levels
- Start with L0 for development
- Upgrade to L1/L2 for production
- Use L3+ for high-value operations
- Document verification methods used
3. Security
- Rotate admin tokens regularly
- Monitor ownership changes closely
- Use domain verification when possible
- Implement proper access controls
4. Monitoring
// Monitor organization activity
const orgActivity = await client.getOrgActivity(orgId, {
startDate: '2024-01-01',
endDate: '2024-01-31'
});
console.log(`Organization created ${orgActivity.passportsCreated} passports`);
console.log(`Members performed ${orgActivity.actionsPerformed} actions`);
Troubleshooting
Common Issues
- User Not Found
- Ensure user exists before adding to organization
- Check user ID format (ap_user_*)
Debug Commands
# Check organization details
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.aport.io/api/orgs/ap_org_12345678"
# List organization members
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.aport.io/api/orgs/ap_org_12345678/members"
# Get owner's passports
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.aport.io/api/owners/ap_org_12345678/passports"
Future Enhancements
- Team Management: Sub-teams within organizations
- Custom Roles: Organization-specific role definitions
- Bulk Operations: Manage multiple passports at once
- Integration APIs: Connect with external identity providers
- Advanced Permissions: Granular permission system