Services Module
The services module (sso.services) manages applications (services), subscription plans, API keys for service-to-service authentication, and AuthOS SAML 2.0 Identity Provider functionality.
Core Service Methods
Method: sso.services.create()
Signature:
create(orgSlug: string, payload: CreateServicePayload): Promise<CreateServiceResponse>
Description: Create a new service for an organization. Requires ‘owner’ or ‘admin’ role.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| payload | CreateServicePayload | Service creation payload |
| payload.slug | string | Unique service slug (URL-friendly identifier) |
| payload.name | string | Service display name |
| payload.service_type | string | Service type (‘web’, ‘mobile’, ‘cli’, ‘api’) |
| payload.github_scopes | string[] (optional) | GitHub OAuth scopes |
| payload.google_scopes | string[] (optional) | Google OAuth scopes |
| payload.microsoft_scopes | string[] (optional) | Microsoft OAuth scopes |
| payload.redirect_uris | string[] | OAuth redirect URIs |
Returns: Promise<CreateServiceResponse> - Created service with details
Response Fields:
| Field | Type | Description |
|---|---|---|
| service | Service | Created service object |
| client_id | string | OAuth client ID for this service |
Example:
const result = await sso.services.create('acme-corp', {
slug: 'main-app',
name: 'Main Application',
service_type: 'web',
github_scopes: ['user:email', 'read:org'],
redirect_uris: ['https://app.acme.com/callback']
});
console.log('Service created with client_id:', result.service.client_id);
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
- When slug is already taken
- When max services limit is reached
Related:
Method: sso.services.list()
Signature:
list(orgSlug: string): Promise<ServiceListResponse>
Description: List all services for an organization.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
Returns: Promise<ServiceListResponse> - Service list response with usage metadata
Response Fields:
| Field | Type | Description |
|---|---|---|
| services | Service[] | Array of service objects |
| usage | ServiceUsage | Service usage statistics |
| usage.current_services | number | Number of services currently created |
| usage.max_services | number | Maximum allowed services |
Example:
const result = await sso.services.list('acme-corp');
console.log(`Using ${result.usage.current_services} of ${result.usage.max_services} services`);
result.services.forEach(svc => console.log(svc.name, svc.client_id));
Throws:
SsoApiError-- When user is not authenticated
- When organization not found
- When user is not a member
Related:
Method: sso.services.get()
Signature:
get(orgSlug: string, serviceSlug: string): Promise<ServiceResponse>
Description: Get detailed information for a specific service.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
Returns: Promise<ServiceResponse> - Service with provider grants and plans
Response Fields:
| Field | Type | Description |
|---|---|---|
| service | Service | Service object |
| provider_grants | ProviderGrant[] | OAuth provider configurations |
| plans | Plan[] | Subscription plans for this service |
Example:
const service = await sso.services.get('acme-corp', 'main-app');
console.log(service.service.redirect_uris);
console.log(service.plans);
Throws:
SsoApiError-- When user is not authenticated
- When service not found
- When user is not a member
Related:
Method: sso.services.update()
Signature:
update(orgSlug: string, serviceSlug: string, payload: UpdateServicePayload): Promise<Service>
Description: Update service configuration. Requires ‘owner’ or ‘admin’ role.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
| payload | UpdateServicePayload | Update payload |
| payload.name | string (optional) | Service display name |
| payload.github_scopes | string[] (optional) | GitHub OAuth scopes |
| payload.google_scopes | string[] (optional) | Google OAuth scopes |
| payload.microsoft_scopes | string[] (optional) | Microsoft OAuth scopes |
| payload.redirect_uris | string[] (optional) | OAuth redirect URIs |
Returns: Promise<Service> - Updated service
Example:
const updated = await sso.services.update('acme-corp', 'main-app', {
name: 'Main Application v2',
redirect_uris: ['https://app.acme.com/callback', 'https://app.acme.com/oauth']
});
console.log('Service updated:', updated.name);
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
- When service not found
Related:
Method: sso.services.delete()
Signature:
delete(orgSlug: string, serviceSlug: string): Promise<void>
Description: Delete a service. Requires ‘owner’ role. This will also delete all associated plans, subscriptions, and API keys.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
Returns: Promise<void>
Example:
await sso.services.delete('acme-corp', 'old-app');
console.log('Service deleted successfully');
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner role
- When service not found
Related:
Plans Module
The plans module (sso.services.plans) manages subscription plans for services.
Method: sso.services.plans.create()
Signature:
plans.create(orgSlug: string, serviceSlug: string, payload: CreatePlanPayload): Promise<PlanResponse>
Description: Create a new subscription plan for a service. Requires ‘owner’ or ‘admin’ role.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
| payload | CreatePlanPayload | Plan creation payload |
| payload.name | string | Plan name |
| payload.price_cents | number | Price in cents (e.g., 2999 for $29.99) |
| payload.currency | string | Currency code (‘usd’, ’eur’, etc.) |
| payload.features | string[] | Array of feature identifiers |
Returns: Promise<PlanResponse> - Created plan with subscription count
Response Fields:
| Field | Type | Description |
|---|---|---|
| plan | Plan | Created plan object |
| subscription_count | number | Number of active subscriptions |
Example:
const result = await sso.services.plans.create('acme-corp', 'main-app', {
name: 'pro',
price_cents: 2999,
currency: 'usd',
features: ['api-access', 'advanced-analytics', 'priority-support']
});
console.log(result.plan.name, result.subscription_count);
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
- When plan name already exists for this service
Related:
Method: sso.services.plans.list()
Signature:
plans.list(orgSlug: string, serviceSlug: string): Promise<PlanResponse[]>
Description: List all plans for a service.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
Returns: Promise<PlanResponse[]> - Array of plans with subscription counts
Example:
const plans = await sso.services.plans.list('acme-corp', 'main-app');
plans.forEach(p => console.log(p.plan.name, p.subscription_count));
Throws:
SsoApiError-- When user is not authenticated
- When service not found
Related:
Method: sso.services.plans.update()
Signature:
plans.update(orgSlug: string, serviceSlug: string, planId: string, payload: UpdatePlanPayload): Promise<PlanResponse>
Description: Update a subscription plan. Requires ‘owner’ or ‘admin’ role.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
| planId | string | Plan ID |
| payload | UpdatePlanPayload | Plan update payload |
| payload.name | string (optional) | Plan name |
| payload.price_cents | number (optional) | Price in cents |
| payload.currency | string (optional) | Currency code |
| payload.features | string[] (optional) | Array of feature identifiers |
Returns: Promise<PlanResponse> - Updated plan with subscription count
Example:
const result = await sso.services.plans.update('acme-corp', 'main-app', 'plan_123', {
name: 'Pro Plus',
price_cents: 3999,
features: ['api-access', 'advanced-analytics', 'priority-support', 'custom-integrations']
});
console.log('Updated plan:', result.plan.name);
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
- When plan not found
Related:
Method: sso.services.plans.delete()
Signature:
plans.delete(orgSlug: string, serviceSlug: string, planId: string): Promise<void>
Description: Delete a subscription plan. Requires ‘owner’ or ‘admin’ role. WARNING: This will fail if the plan has active subscriptions. You must migrate or cancel all subscriptions before deleting a plan.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
| planId | string | Plan ID |
Returns: Promise<void>
Example:
try {
await sso.services.plans.delete('acme-corp', 'main-app', 'plan_123');
console.log('Plan deleted successfully');
} catch (error) {
console.error('Cannot delete plan with active subscriptions');
}
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
- When plan has active subscriptions
- When plan not found
Related:
API Keys Module
The API keys module (sso.services.apiKeys) manages API keys for service-to-service authentication.
Method: sso.services.apiKeys.create()
Signature:
apiKeys.create(orgSlug: string, serviceSlug: string, payload: CreateApiKeyPayload): Promise<ApiKeyCreateResponse>
Description: Create a new API key for a service. Requires ‘owner’ or ‘admin’ role. IMPORTANT: The full API key is only returned once upon creation. Store it securely as it cannot be retrieved again.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
| payload | CreateApiKeyPayload | API key creation payload |
| payload.name | string | Descriptive name for the API key |
| payload.permissions | string[] | Array of permission scopes |
| payload.expires_in_days | number (optional) | Days until expiration (default: never) |
Returns: Promise<ApiKeyCreateResponse> - Created API key with the full key value
Response Fields:
| Field | Type | Description |
|---|---|---|
| id | string | API key ID |
| key | string | Full API key (only shown once) |
| prefix | string | Key prefix for identification |
| name | string | API key name |
| permissions | string[] | Granted permissions |
| expires_at | string (optional) | ISO timestamp of expiration |
| created_at | string | ISO timestamp of creation |
Example:
const apiKey = await sso.services.apiKeys.create('acme-corp', 'main-app', {
name: 'Production Backend',
permissions: ['read:users', 'write:subscriptions'],
expires_in_days: 90
});
// IMPORTANT: Store this key securely - it won't be shown again
console.log('API Key:', apiKey.key);
console.log('Prefix:', apiKey.prefix);
// Store in environment variable or secrets manager
process.env.SSO_API_KEY = apiKey.key;
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
- When invalid permissions are specified
Related:
Method: sso.services.apiKeys.list()
Signature:
apiKeys.list(orgSlug: string, serviceSlug: string, options?: { limit?: number; offset?: number }): Promise<ListApiKeysResponse>
Description: List all API keys for a service. Note: The full key values are not included in this response.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
| options | object (optional) | Query parameters for pagination |
| options.limit | number (optional) | Items per page (default: 50) |
| options.offset | number (optional) | Offset for pagination (default: 0) |
Returns: Promise<ListApiKeysResponse> - List of API keys with metadata
Response Fields:
| Field | Type | Description |
|---|---|---|
| api_keys | ApiKey[] | Array of API key objects (without full keys) |
| total | number | Total number of API keys |
Example:
const result = await sso.services.apiKeys.list('acme-corp', 'main-app', {
limit: 50,
offset: 0
});
console.log(`Total API keys: ${result.total}`);
result.api_keys.forEach(key => {
console.log(`${key.name} (${key.prefix})`);
console.log(`Permissions: ${key.permissions.join(', ')}`);
console.log(`Last used: ${key.last_used_at || 'Never'}`);
});
Throws:
SsoApiError-- When user is not authenticated
- When service not found
Related:
Method: sso.services.apiKeys.get()
Signature:
apiKeys.get(orgSlug: string, serviceSlug: string, apiKeyId: string): Promise<ApiKey>
Description: Get details for a specific API key. Note: The full key value is not included in this response.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
| apiKeyId | string | API key ID |
Returns: Promise<ApiKey> - API key details
Response Fields:
| Field | Type | Description |
|---|---|---|
| id | string | API key ID |
| prefix | string | Key prefix |
| name | string | API key name |
| permissions | string[] | Granted permissions |
| expires_at | string (optional) | ISO timestamp of expiration |
| last_used_at | string (optional) | ISO timestamp of last use |
| created_at | string | ISO timestamp of creation |
Example:
const apiKey = await sso.services.apiKeys.get('acme-corp', 'main-app', 'key_abc123');
console.log(`Name: ${apiKey.name}`);
console.log(`Permissions: ${apiKey.permissions.join(', ')}`);
console.log(`Expires: ${apiKey.expires_at || 'Never'}`);
Throws:
SsoApiError-- When user is not authenticated
- When API key not found
Related:
Method: sso.services.apiKeys.delete()
Signature:
apiKeys.delete(orgSlug: string, serviceSlug: string, apiKeyId: string): Promise<void>
Description: Delete an API key. Requires ‘owner’ or ‘admin’ role. WARNING: This action is immediate and cannot be undone. Any services using this key will lose access immediately.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
| apiKeyId | string | API key ID |
Returns: Promise<void>
Example:
await sso.services.apiKeys.delete('acme-corp', 'main-app', 'key_abc123');
console.log('API key deleted successfully');
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
- When API key not found
Related:
SAML Module
The SAML module (sso.services.saml) configures AuthOS SAML 2.0 Identity Provider functionality, allowing your service to provide SSO into third-party applications.
Method: sso.services.saml.configure()
Signature:
saml.configure(orgSlug: string, serviceSlug: string, payload: ConfigureSamlPayload): Promise<ConfigureSamlResponse>
Description: Configure SAML IdP settings for a service. Requires ‘owner’ or ‘admin’ role.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
| payload | ConfigureSamlPayload | SAML configuration payload |
| payload.enabled | boolean | Whether SAML is enabled |
| payload.entity_id | string | Service Provider entity ID |
| payload.acs_url | string | Assertion Consumer Service URL |
| payload.name_id_format | string | NameID format |
| payload.attribute_mapping | object | Attribute mapping configuration |
| payload.sign_assertions | boolean | Whether to sign SAML assertions |
| payload.sign_response | boolean | Whether to sign SAML response |
Returns: Promise<ConfigureSamlResponse> - Configuration success response
Response Fields:
| Field | Type | Description |
|---|---|---|
| message | string | Confirmation message |
Example:
const result = await sso.services.saml.configure('acme-corp', 'main-app', {
enabled: true,
entity_id: 'https://salesforce.example.com',
acs_url: 'https://salesforce.example.com/saml/acs',
name_id_format: 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
attribute_mapping: {
email: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress',
id: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name'
},
sign_assertions: true,
sign_response: true
});
console.log(result.message); // "SAML configuration updated successfully"
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
- When configuration is invalid
Related:
Method: sso.services.saml.getConfig()
Signature:
saml.getConfig(orgSlug: string, serviceSlug: string): Promise<SamlConfig>
Description: Get current SAML IdP configuration for a service.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
Returns: Promise<SamlConfig> - Current SAML configuration
Response Fields:
| Field | Type | Description |
|---|---|---|
| enabled | boolean | Whether SAML is enabled |
| entity_id | string | Service Provider entity ID |
| acs_url | string | Assertion Consumer Service URL |
| name_id_format | string | NameID format |
| attribute_mapping | object | Attribute mapping configuration |
| sign_assertions | boolean | Whether assertions are signed |
| sign_response | boolean | Whether response is signed |
| has_certificate | boolean | Whether a certificate exists |
Example:
const config = await sso.services.saml.getConfig('acme-corp', 'main-app');
if (config.enabled && config.has_certificate) {
console.log('SAML IdP is ready');
console.log('Entity ID:', config.entity_id);
console.log('ACS URL:', config.acs_url);
}
Throws:
SsoApiError-- When user is not authenticated
- When service not found
Related:
Method: sso.services.saml.deleteConfig()
Signature:
saml.deleteConfig(orgSlug: string, serviceSlug: string): Promise<ConfigureSamlResponse>
Description: Delete SAML IdP configuration and deactivate all certificates. Requires ‘owner’ or ‘admin’ role. WARNING: This will break SSO for all third-party applications using this IdP.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
Returns: Promise<ConfigureSamlResponse> - Deletion confirmation
Example:
await sso.services.saml.deleteConfig('acme-corp', 'main-app');
console.log('SAML IdP configuration deleted');
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
Related:
Method: sso.services.saml.generateCertificate()
Signature:
saml.generateCertificate(orgSlug: string, serviceSlug: string): Promise<SamlCertificate>
Description: Generate a new SAML signing certificate for the IdP. Requires ‘owner’ or ‘admin’ role. IMPORTANT: This automatically deactivates any existing active certificates. Provide the returned certificate to your Service Provider during SAML setup.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
Returns: Promise<SamlCertificate> - Certificate information including public key
Response Fields:
| Field | Type | Description |
|---|---|---|
| id | string | Certificate ID |
| public_key | string | PEM-encoded public certificate |
| valid_from | string | ISO timestamp of validity start |
| valid_until | string | ISO timestamp of validity end |
| is_active | boolean | Whether certificate is active |
Example:
const cert = await sso.services.saml.generateCertificate('acme-corp', 'main-app');
console.log('Certificate generated, valid until:', cert.valid_until);
console.log('Public certificate:\n', cert.public_key);
// Provide cert.public_key to your Service Provider
Throws:
SsoApiError-- When user is not authenticated
- When user doesn’t have owner/admin role
- When SAML is not configured
Related:
Method: sso.services.saml.getCertificate()
Signature:
saml.getCertificate(orgSlug: string, serviceSlug: string): Promise<SamlCertificate>
Description: Get the active SAML signing certificate.
Parameters:
| Name | Type | Description |
|---|---|---|
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
Returns: Promise<SamlCertificate> - Active certificate information
Example:
try {
const cert = await sso.services.saml.getCertificate('acme-corp', 'main-app');
console.log('Certificate expires:', cert.valid_until);
} catch (error) {
console.log('No active certificate - generate one first');
}
Throws:
SsoApiError-- When user is not authenticated
- When no active certificate exists
Related:
Method: sso.services.saml.getMetadataUrl()
Signature:
saml.getMetadataUrl(baseURL: string, orgSlug: string, serviceSlug: string): string
Description: Get the SAML IdP metadata URL for this service. This URL can be provided to Service Providers for automatic configuration.
Parameters:
| Name | Type | Description |
|---|---|---|
| baseURL | string | AuthOS base URL |
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
Returns: string - Metadata URL
Example:
const metadataUrl = sso.services.saml.getMetadataUrl(
'https://sso.example.com',
'acme-corp',
'main-app'
);
console.log('Provide this URL to your SP:', metadataUrl);
// https://sso.example.com/saml/acme-corp/main-app/metadata
Related:
Method: sso.services.saml.getSsoUrl()
Signature:
saml.getSsoUrl(baseURL: string, orgSlug: string, serviceSlug: string): string
Description: Get the SAML SSO endpoint URL for this service. This is where Service Providers should redirect users to initiate SSO.
Parameters:
| Name | Type | Description |
|---|---|---|
| baseURL | string | AuthOS base URL |
| orgSlug | string | Organization slug |
| serviceSlug | string | Service slug |
Returns: string - SSO endpoint URL
Example:
const ssoUrl = sso.services.saml.getSsoUrl(
'https://sso.example.com',
'acme-corp',
'main-app'
);
console.log('SSO endpoint:', ssoUrl);
// https://sso.example.com/saml/acme-corp/main-app/sso
Related:
Type Definitions
Service
interface Service {
id: string;
organization_id: string;
slug: string;
name: string;
service_type: 'web' | 'mobile' | 'cli' | 'api';
client_id: string;
redirect_uris: string[];
created_at: string;
updated_at: string;
}
ServiceResponse
interface ServiceResponse {
service: Service;
provider_grants: ProviderGrant[];
plans: Plan[];
}
ServiceListResponse
interface ServiceListResponse {
services: Service[];
usage: ServiceUsage;
}
CreateServicePayload
interface CreateServicePayload {
slug: string;
name: string;
service_type: 'web' | 'mobile' | 'cli' | 'api';
github_scopes?: string[];
google_scopes?: string[];
microsoft_scopes?: string[];
redirect_uris: string[];
}
CreateServiceResponse
interface CreateServiceResponse {
service: Service;
client_id: string;
}
UpdateServicePayload
interface UpdateServicePayload {
name?: string;
github_scopes?: string[];
google_scopes?: string[];
microsoft_scopes?: string[];
redirect_uris?: string[];
}
Plan
interface Plan {
id: string;
service_id: string;
name: string;
price_cents: number;
currency: string;
features: string[];
created_at: string;
updated_at: string;
}
PlanResponse
interface PlanResponse {
plan: Plan;
subscription_count: number;
}
CreatePlanPayload
interface CreatePlanPayload {
name: string;
price_cents: number;
currency: string;
features: string[];
}
UpdatePlanPayload
interface UpdatePlanPayload {
name?: string;
price_cents?: number;
currency?: string;
features?: string[];
}
ApiKey
interface ApiKey {
id: string;
prefix: string;
name: string;
permissions: string[];
expires_at?: string;
last_used_at?: string;
created_at: string;
}
ApiKeyCreateResponse
interface ApiKeyCreateResponse {
id: string;
key: string;
prefix: string;
name: string;
permissions: string[];
expires_at?: string;
created_at: string;
}
CreateApiKeyPayload
interface CreateApiKeyPayload {
name: string;
permissions: string[];
expires_in_days?: number;
}
ListApiKeysResponse
interface ListApiKeysResponse {
api_keys: ApiKey[];
total: number;
}
SamlConfig
interface SamlConfig {
enabled: boolean;
entity_id: string;
acs_url: string;
name_id_format: string;
attribute_mapping: Record<string, string>;
sign_assertions: boolean;
sign_response: boolean;
has_certificate: boolean;
}
ConfigureSamlPayload
interface ConfigureSamlPayload {
enabled: boolean;
entity_id: string;
acs_url: string;
name_id_format: string;
attribute_mapping: Record<string, string>;
sign_assertions: boolean;
sign_response: boolean;
}
ConfigureSamlResponse
interface ConfigureSamlResponse {
message: string;
}
SamlCertificate
interface SamlCertificate {
id: string;
public_key: string;
valid_from: string;
valid_until: string;
is_active: boolean;
}
API Key Permissions
Available permissions for API keys:
User Management:
read:users- View user informationwrite:users- Create and update users
Subscription Management:
read:subscriptions- View subscriptionswrite:subscriptions- Create and update subscriptions
Analytics:
read:analytics- View service analytics
Service Configuration:
read:service- View service configurationwrite:service- Update service configuration