scim

package
v0.0.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 4, 2026 License: Apache-2.0 Imports: 36 Imported by: 0

README

SCIM 2.0 Provisioning Plugin

Enterprise-grade SCIM 2.0 implementation for automated user and group provisioning from identity providers like Okta, Azure AD, OneLogin, and others.

Overview

The SCIM (System for Cross-domain Identity Management) 2.0 plugin enables enterprise customers to:

  • Automate User Provisioning: Create, update, and deactivate users automatically
  • Group Synchronization: Sync SCIM groups to AuthSome teams/roles
  • Real-time Updates: Immediate synchronization of identity changes
  • Bulk Operations: Efficiently provision multiple users at once
  • Custom Attribute Mapping: Flexible schema mapping for custom attributes
  • JIT Provisioning: Just-In-Time user creation on first login
  • Enterprise Integration: Works with Okta, Azure AD, OneLogin, Google Workspace, etc.

Architecture Modes

SCIM supports dual-mode operation to work with different deployment configurations:

App Mode (Multitenancy Only)
  • SCIM provisions users/groups directly into platform apps
  • Uses multitenancy app service (*app.Service)
  • Users are app members, groups are app teams
  • Simpler deployment without organization plugin
  • Token organization_id field contains the app ID
Organization Mode (With Organization Plugin)
  • SCIM provisions users/groups into user-created organizations
  • Uses organization plugin service (*organization.Service)
  • Users are organization members, groups are organization teams
  • Full 3-tier: App → Environment → Organization
  • Token includes app_id, environment_id, and organization_id

The plugin automatically detects which service is available and uses the appropriate mode.

Features

✅ SCIM 2.0 Standard Compliance
  • Full RFC 7643 and RFC 7644 compliance
  • Core User schema (RFC 7643 Section 4.1)
  • Enterprise User extension (RFC 7643 Section 4.3)
  • Group schema (RFC 7643 Section 4.2)
  • Service Provider Configuration endpoint
  • Resource Type and Schema discovery
🔐 Security
  • Bearer token authentication
  • Organization-scoped isolation
  • IP whitelisting support
  • Rate limiting per organization
  • Complete audit logging
  • Secure token generation and storage
📊 Operations Supported

User Operations:

  • POST /scim/v2/Users - Create user
  • GET /scim/v2/Users - List users with filtering
  • GET /scim/v2/Users/:id - Get user by ID
  • PUT /scim/v2/Users/:id - Replace user (full update)
  • PATCH /scim/v2/Users/:id - Update user (partial)
  • DELETE /scim/v2/Users/:id - Deactivate/delete user

Group Operations:

  • POST /scim/v2/Groups - Create group
  • GET /scim/v2/Groups - List groups
  • GET /scim/v2/Groups/:id - Get group by ID
  • PUT /scim/v2/Groups/:id - Replace group
  • PATCH /scim/v2/Groups/:id - Update group
  • DELETE /scim/v2/Groups/:id - Delete group

Bulk Operations:

  • POST /scim/v2/Bulk - Process multiple operations in a single request

Search:

  • POST /scim/v2/.search - Search across resources with filtering

Discovery:

  • GET /scim/v2/ServiceProviderConfig - Service provider capabilities
  • GET /scim/v2/ResourceTypes - Supported resource types
  • GET /scim/v2/Schemas - Supported schemas

Installation

1. Add Plugin to Your AuthSome Instance

App Mode (Multitenancy only):

package main

import (
    "github.com/xraph/authsome"
    "github.com/xraph/authsome/plugins/multiapp"
    "github.com/xraph/authsome/plugins/enterprise/scim"
)

func main() {
    // Create AuthSome instance
    auth := authsome.New(
        authsome.WithDatabase(db),
        authsome.WithForgeApp(app),
    )
    
    // Register multitenancy plugin (required for app mode)
    if err := auth.RegisterPlugin(multitenancy.NewPlugin()); err != nil {
        panic(err)
    }
    
    // Register SCIM plugin
    scimPlugin := scim.NewPlugin()
    if err := auth.RegisterPlugin(scimPlugin); err != nil {
        panic(err)
    }
    
    // Initialize AuthSome (this will initialize all plugins)
    if err := auth.Initialize(ctx); err != nil {
        panic(err)
    }
    
    // Mount routes
    if err := auth.Mount(router, "/api/auth"); err != nil {
        panic(err)
    }
}

Organization Mode (With organization plugin):

package main

import (
    "github.com/xraph/authsome"
    "github.com/xraph/authsome/plugins/multiapp"
    "github.com/xraph/authsome/plugins/organization"
    "github.com/xraph/authsome/plugins/enterprise/scim"
)

func main() {
    // Create AuthSome instance
    auth := authsome.New(
        authsome.WithDatabase(db),
        authsome.WithForgeApp(app),
    )
    
    // Register multitenancy plugin (for apps/environments)
    if err := auth.RegisterPlugin(multitenancy.NewPlugin()); err != nil {
        panic(err)
    }
    
    // Register organization plugin (required for organization mode)
    if err := auth.RegisterPlugin(organization.NewPlugin()); err != nil {
        panic(err)
    }
    
    // Register SCIM plugin
    scimPlugin := scim.NewPlugin()
    if err := auth.RegisterPlugin(scimPlugin); err != nil {
        panic(err)
    }
    
    // Initialize AuthSome (this will initialize all plugins)
    if err := auth.Initialize(ctx); err != nil {
        panic(err)
    }
    
    // Mount routes
    if err := auth.Mount(router, "/api/auth"); err != nil {
        panic(err)
    }
}
2. Configure Plugin
# config.yaml
auth:
  plugins:
    # Multitenancy plugin (required for app mode, or for apps/environments in org mode)
    multitenancy:
      enabled: true
      enableAppCreation: true
    
    # Organization plugin (optional - enables organization mode)
    organization:
      enabled: true
      enableUserCreation: true
    
    # SCIM plugin
    scim:
      enabled: true
      auth_method: "bearer"
      token_expiry: "90d"
      
      rate_limit:
        enabled: true
        requests_per_min: 600  # 10 req/sec
        burst_size: 100
      
      user_provisioning:
        enabled: true
        auto_activate: true
        send_welcome_email: false
        default_role: "member"
        prevent_duplicates: true
        soft_delete_on_deprovision: true
      
      group_sync:
        enabled: true
        sync_to_teams: true
        sync_to_roles: false
        create_missing_groups: true
      
      bulk_operations:
        enabled: true
        max_operations: 100
        max_payload_bytes: 1048576  # 1MB
      
      search:
        max_results: 1000
        default_results: 50
      
      security:
        require_https: true
        audit_all_operations: true
        mask_sensitive_data: true
        require_org_validation: true

Note: SCIM automatically detects which mode to use:

  • If only multitenancy plugin is loaded → App Mode (provisions to apps)
  • If organization plugin is also loaded → Organization Mode (provisions to user-created organizations)
3. Run Database Migrations

Migrations run automatically when the plugin is initialized. You can also run them manually:

if err := scimPlugin.Migrate(); err != nil {
    panic(err)
}

Usage

Creating a Provisioning Token

Before you can use SCIM, create a provisioning token for your identity provider. The token is scoped to the current app/environment/organization context:

App Mode:

  • Token is scoped to the app (organization_id = app_id)
  • Provisions users/groups directly into the app

Organization Mode:

  • Token is scoped to a specific organization within an app/environment
  • Provisions users/groups into the user-created organization
curl -X POST http://localhost:8080/api/admin/scim/tokens \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Okta Production",
    "description": "SCIM token for Okta production environment",
    "scopes": ["scim:read", "scim:write"],
    "expires_at": "2025-12-31T23:59:59Z"
  }'

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "id": "cm3abc123def456ghi789",
  "name": "Okta Production",
  "message": "Store this token securely. It will not be shown again."
}

⚠️ Important: Save the token immediately. It will not be displayed again.

Configuring Your Identity Provider
Okta
  1. Navigate to Applications > Applications in Okta Admin Console
  2. Click Browse App Catalog
  3. Search for SCIM 2.0 Test App (Header Auth)
  4. Click Add Integration
  5. Configure:
    • SCIM 2.0 Base URL: https://your-domain.com/scim/v2
    • Unique identifier field for users: userName
    • Supported provisioning actions: Check all
    • Authentication Mode: HTTP Header
    • Authorization: Bearer YOUR_SCIM_TOKEN
Azure AD
  1. Navigate to Azure Active Directory > Enterprise Applications
  2. Click New Application > Create your own application
  3. Select Integrate any other application you don't find in the gallery (Non-gallery)
  4. Go to Provisioning > Automatic
  5. Configure:
    • Tenant URL: https://your-domain.com/scim/v2
    • Secret Token: YOUR_SCIM_TOKEN
  6. Test connection and save
OneLogin
  1. Navigate to Applications > Custom Connectors
  2. Click New Connector
  3. Select SCIM 2.0
  4. Configure:
    • SCIM Base URL: https://your-domain.com/scim/v2
    • SCIM Bearer Token: YOUR_SCIM_TOKEN
    • SCIM Version: 2.0
  5. Enable provisioning features
Example: Provisioning a User

When you assign a user in your IdP, it will automatically create the user in AuthSome:

SCIM Request (from IdP):

POST /scim/v2/Users HTTP/1.1
Host: your-domain.com
Authorization: Bearer YOUR_SCIM_TOKEN
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
  "userName": "bjensen@example.com",
  "name": {
    "givenName": "Barbara",
    "familyName": "Jensen"
  },
  "emails": [{
    "value": "bjensen@example.com",
    "type": "work",
    "primary": true
  }],
  "displayName": "Barbara Jensen",
  "active": true,
  "externalId": "okta_user_12345"
}

Response:

HTTP/1.1 201 Created
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
  "id": "cm3xyz789abc123def456",
  "externalId": "okta_user_12345",
  "userName": "bjensen@example.com",
  "name": {
    "givenName": "Barbara",
    "familyName": "Jensen",
    "formatted": "Barbara Jensen"
  },
  "emails": [{
    "value": "bjensen@example.com",
    "type": "work",
    "primary": true
  }],
  "displayName": "Barbara Jensen",
  "active": true,
  "meta": {
    "resourceType": "User",
    "created": "2024-01-15T10:30:00Z",
    "lastModified": "2024-01-15T10:30:00Z",
    "location": "/scim/v2/Users/cm3xyz789abc123def456"
  }
}
Example: Updating a User

SCIM Request (PATCH):

PATCH /scim/v2/Users/cm3xyz789abc123def456 HTTP/1.1
Host: your-domain.com
Authorization: Bearer YOUR_SCIM_TOKEN
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "active",
      "value": false
    }
  ]
}
Example: Bulk Provisioning
POST /scim/v2/Bulk HTTP/1.1
Host: your-domain.com
Authorization: Bearer YOUR_SCIM_TOKEN
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
  "failOnErrors": 1,
  "Operations": [
    {
      "method": "POST",
      "path": "/Users",
      "bulkId": "qwerty",
      "data": {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
        "userName": "alice@example.com",
        "name": {
          "givenName": "Alice",
          "familyName": "Smith"
        },
        "emails": [{
          "value": "alice@example.com",
          "type": "work"
        }]
      }
    },
    {
      "method": "POST",
      "path": "/Users",
      "bulkId": "ytrewq",
      "data": {
        "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
        "userName": "bob@example.com",
        "name": {
          "givenName": "Bob",
          "familyName": "Johnson"
        },
        "emails": [{
          "value": "bob@example.com",
          "type": "work"
        }]
      }
    }
  ]
}

Attribute Mapping

The plugin supports flexible attribute mapping to adapt to your schema:

Default Mappings
SCIM Attribute AuthSome Field
userName email
emails[0].value email
name.givenName name (first part)
name.familyName name (last part)
displayName name
active email_verified
externalId metadata.scim_external_id
Enterprise Extension Mappings
SCIM Attribute AuthSome Field
urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber metadata.employee_number
urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department metadata.department
urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:manager.value metadata.manager_id
Custom Mappings

Configure custom attribute mappings:

attribute_mapping:
  enabled: true
  custom_mapping:
    "customAttribute1": "metadata.custom_field_1"
    "customAttribute2": "metadata.custom_field_2"

Group Synchronization

SCIM groups can be automatically synced to AuthSome teams or roles:

Configuration
group_sync:
  enabled: true
  sync_to_teams: true           # Sync to teams
  sync_to_roles: false          # Or sync to roles
  create_missing_groups: true   # Auto-create teams/roles
  delete_empty_groups: false    # Keep empty groups
Example: Creating a Group
POST /scim/v2/Groups HTTP/1.1
Host: your-domain.com
Authorization: Bearer YOUR_SCIM_TOKEN
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
  "displayName": "Engineering",
  "externalId": "okta_group_engineering",
  "members": [
    {
      "value": "cm3xyz789abc123def456",
      "display": "Barbara Jensen"
    }
  ]
}
SCIM-Managed Team Tracking

Teams created via SCIM provisioning are automatically marked with special tracking fields to distinguish them from manually-created teams:

  • provisionedBy: Set to "scim" for SCIM-created teams
  • externalID: Stores the external system's identifier (e.g., Okta group ID)
Behavior

Manual Modifications:

  • SCIM-managed teams can still be updated or deleted via regular team APIs
  • Operations on SCIM-managed teams return warnings in the response
  • Changes made manually may be overwritten by the identity provider

Warning Response Example:

When updating a SCIM-managed team via the regular team API:

{
  "data": {
    "id": "cm3xyz789abc123def456",
    "name": "Engineering",
    "description": "Engineering team",
    "provisionedBy": "scim",
    "externalID": "okta_group_engineering"
  },
  "warnings": [
    {
      "code": "scim_managed_team",
      "message": "This team is managed via SCIM provisioning. Manual changes may be overwritten by the identity provider."
    }
  ]
}

Team Response Fields:

All teams now include provisioning information in their responses:

{
  "id": "cm3xyz789abc123def456",
  "name": "Engineering",
  "description": "Team description",
  "provisionedBy": "scim",          // Only present for SCIM-managed teams
  "externalID": "okta_group_123",   // Only present for SCIM-managed teams
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}

Best Practices:

  1. Identity Provider as Source of Truth: When using SCIM, treat the identity provider as the authoritative source for team management
  2. Manual Changes: Use manual updates only for emergency situations or temporary fixes
  3. Monitoring: Watch for warning responses when modifying teams to identify potential conflicts
  4. Audit Trail: Review SCIM provisioning logs to track all changes made via identity provider
SCIM-Managed Team Memberships

Similar to teams, team memberships created via SCIM are tracked with a provisioning field:

  • provisionedBy: Set to "scim" for SCIM-added members
Team Member Tracking

When SCIM adds a user to a group (team), the membership relationship is marked as SCIM-managed:

{
  "id": "cm3xyz789abc123def456",
  "teamID": "cm3team123",
  "memberID": "cm3member456",
  "provisionedBy": "scim",        // Indicates SCIM-managed membership
  "joinedAt": "2024-01-15T10:30:00Z",
  "createdAt": "2024-01-15T10:30:00Z"
}

Use Cases:

  1. Membership Audit: Identify which team memberships are controlled by identity provider
  2. Access Reviews: Distinguish between manually-granted and SCIM-provisioned access
  3. Compliance: Track provisioned access for regulatory requirements
  4. Conflict Detection: Services can check provisionedBy before manual member removal

Example Service Check:

// Check if team membership is SCIM-managed before removal
teamMember, err := teamService.GetTeamMember(ctx, teamID, memberID)
if err != nil {
    return err
}

if teamMember.ProvisionedBy != nil && *teamMember.ProvisionedBy == "scim" {
    log.Warn("Attempting to remove SCIM-managed team member",
        "team", teamID,
        "member", memberID)
    // Optionally return warning to user
}

Important Notes:

  • Team membership removal via regular APIs is allowed even for SCIM-managed members
  • Identity provider will re-provision the member on next sync if they're still in the group
  • For complete removal, remove the user from the group in the identity provider

Monitoring & Audit

Viewing Provisioning Logs
curl -X GET "http://localhost:8080/api/scim-admin/logs?start_date=2024-01-01&limit=50" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"
Provisioning Statistics
curl -X GET "http://localhost:8080/api/scim-admin/stats?start_date=2024-01-01&end_date=2024-01-31" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN"

Response:

{
  "total_operations": 1250,
  "successful_operations": 1238,
  "failed_operations": 12,
  "success_rate": 99.04,
  "operations_by_type": {
    "CREATE_USER": 500,
    "UPDATE_USER": 650,
    "DELETE_USER": 100
  },
  "average_duration_ms": 125.5
}

Webhooks

Send provisioning events to external systems:

webhooks:
  enabled: true
  notify_on_create: true
  notify_on_update: true
  notify_on_delete: true
  notify_on_group_sync: true
  webhook_urls:
    - "https://your-webhook-endpoint.com/scim-events"
  retry_attempts: 3
  timeout_seconds: 10

Troubleshooting

Common Issues
1. "Invalid or expired token"

Cause: Bearer token is invalid, expired, or revoked.

Solution: Generate a new provisioning token and update your IdP configuration.

2. "Rate limit exceeded"

Cause: Too many requests in a short period.

Solution:

  • Increase rate_limit.requests_per_min in config
  • Implement exponential backoff in your IdP
  • Use bulk operations for multiple users
3. "User with email already exists"

Cause: Duplicate email address.

Solution:

  • Set user_provisioning.prevent_duplicates: false to allow duplicates
  • Or ensure unique emails in your IdP
4. "Group synchronization failed"

Cause: Group sync is disabled or team/role doesn't exist.

Solution:

  • Enable group sync in configuration
  • Set group_sync.create_missing_groups: true
Testing SCIM Endpoints

Use the SCIM 2.0 Test Tool:

# Test Service Provider Config
curl http://localhost:8080/scim/v2/ServiceProviderConfig \
  -H "Authorization: Bearer YOUR_SCIM_TOKEN"

# Test User Listing
curl http://localhost:8080/scim/v2/Users \
  -H "Authorization: Bearer YOUR_SCIM_TOKEN"

# Test User Creation
curl -X POST http://localhost:8080/scim/v2/Users \
  -H "Authorization: Bearer YOUR_SCIM_TOKEN" \
  -H "Content-Type: application/scim+json" \
  -d '{"schemas":["urn:ietf:params:scim:schemas:core:2.0:User"],"userName":"test@example.com"}'

Performance

Benchmarks
  • User creation: ~100ms p99 (including database write)
  • User lookup: ~10ms p99 (cached)
  • Bulk operations: ~500ms for 100 users
  • Rate limit: 600 requests/min per organization (configurable)
Optimization Tips
  1. Enable Bulk Operations: Use bulk endpoint for provisioning multiple users
  2. Increase Rate Limits: Adjust based on your needs
  3. Use Caching: Redis caching for attribute lookups
  4. Index Database: Ensure indexes on email, external_id

Security Best Practices

  1. Use HTTPS: Always use HTTPS in production
  2. Rotate Tokens: Regularly rotate provisioning tokens
  3. IP Whitelist: Restrict access to known IdP IPs
  4. Audit Logs: Monitor provisioning logs for suspicious activity
  5. Least Privilege: Use minimal scopes for tokens
  6. Soft Delete: Enable soft delete to prevent accidental data loss

Support

For issues, feature requests, or questions:

License

This plugin is part of the AuthSome framework and follows the same license.


Made with ❤️ by the AuthSome Team

Documentation

Index

Examples

Constants

View Source
const (
	PluginID      = "scim"
	PluginName    = "SCIM 2.0 Provisioning"
	PluginVersion = "1.0.0"
)
View Source
const (
	SchemaCore            = "urn:ietf:params:scim:schemas:core:2.0:User"
	SchemaEnterprise      = "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
	SchemaGroup           = "urn:ietf:params:scim:schemas:core:2.0:Group"
	SchemaServiceProvider = "urn:ietf:params:scim:schemas:core:2.0:ServiceProviderConfig"
	SchemaResourceType    = "urn:ietf:params:scim:schemas:core:2.0:ResourceType"
	SchemaSchema          = "urn:ietf:params:scim:schemas:core:2.0:Schema"
	SchemaListResponse    = "urn:ietf:params:scim:api:messages:2.0:ListResponse"
	SchemaError           = "urn:ietf:params:scim:api:messages:2.0:Error"
	SchemaBulkRequest     = "urn:ietf:params:scim:api:messages:2.0:BulkRequest"
	SchemaBulkResponse    = "urn:ietf:params:scim:api:messages:2.0:BulkResponse"
	SchemaPatchOp         = "urn:ietf:params:scim:api:messages:2.0:PatchOp"
)

SCIM 2.0 Schema URNs (RFC 7643)

Variables

This section is empty.

Functions

This section is empty.

Types

type Attribute

type Attribute struct {
	Name            string      `json:"name"`
	Type            string      `json:"type"` // string, boolean, decimal, integer, dateTime, reference, complex, binary
	MultiValued     bool        `json:"multiValued"`
	Description     string      `json:"description,omitempty"`
	Required        bool        `json:"required"`
	CanonicalValues []string    `json:"canonicalValues,omitempty"`
	CaseExact       bool        `json:"caseExact"`
	Mutability      string      `json:"mutability"` // readOnly, readWrite, immutable, writeOnly
	Returned        string      `json:"returned"`   // always, never, default, request
	Uniqueness      string      `json:"uniqueness"` // none, server, global
	SubAttributes   []Attribute `json:"subAttributes,omitempty"`
	ReferenceTypes  []string    `json:"referenceTypes,omitempty"`
}

Attribute represents a schema attribute (RFC 7643 Section 7)

type AttributeMapping

type AttributeMapping struct {
	bun.BaseModel  `bun:"table:attribute_mappings,alias:am"`
	ID             xid.ID                 `bun:"id,pk,type:varchar(20)"`
	AppID          xid.ID                 `bun:"app_id,type:varchar(20),notnull"`                                    // Platform app
	EnvironmentID  xid.ID                 `bun:"environment_id,type:varchar(20),notnull"`                            // Target environment
	OrganizationID xid.ID                 `bun:"organization_id,type:varchar(20),notnull,unique:org_mapping_unique"` // User-created organization
	Mappings       map[string]string      `bun:"mappings,type:jsonb,notnull"`                                        // SCIM attr -> AuthSome field
	Metadata       map[string]interface{} `bun:"metadata,type:jsonb"`
	CreatedAt      time.Time              `bun:"created_at,notnull"`
	UpdatedAt      time.Time              `bun:"updated_at,notnull"`
}

AttributeMapping represents custom attribute mappings per organization Updated for 3-tier architecture: App → Environment → Organization

type AttributeMappingConfig

type AttributeMappingConfig struct {
	Enabled       bool              `json:"enabled" yaml:"enabled"`
	CustomMapping map[string]string `json:"custom_mapping" yaml:"custom_mapping"` // Map SCIM attribute to AuthSome field

	// Standard SCIM User schema mappings (RFC 7643)
	UserNameField    string `json:"username_field" yaml:"username_field"`         // Default: "userName"
	EmailField       string `json:"email_field" yaml:"email_field"`               // Default: "emails[0].value"
	GivenNameField   string `json:"given_name_field" yaml:"given_name_field"`     // Default: "name.givenName"
	FamilyNameField  string `json:"family_name_field" yaml:"family_name_field"`   // Default: "name.familyName"
	DisplayNameField string `json:"display_name_field" yaml:"display_name_field"` // Default: "displayName"
	ActiveField      string `json:"active_field" yaml:"active_field"`             // Default: "active"

	// Enterprise schema extension (urn:ietf:params:scim:schemas:extension:enterprise:2.0:User)
	EmployeeNumberField string `json:"employee_number_field" yaml:"employee_number_field"` // Default: "employeeNumber"
	DepartmentField     string `json:"department_field" yaml:"department_field"`           // Default: "department"
	ManagerField        string `json:"manager_field" yaml:"manager_field"`                 // Default: "manager.value"
}

AttributeMappingConfig configures custom attribute mapping

type AttributeMappingsResponse

type AttributeMappingsResponse struct {
	ID       string            `json:"id"`
	Mappings map[string]string `json:"mappings"`
}

AttributeMappingsResponse is the response for attribute mappings

type AuthenticationScheme

type AuthenticationScheme struct {
	Type             string `json:"type"` // oauth, oauth2, oauthbearertoken, httpbasic, httpdigest
	Name             string `json:"name"`
	Description      string `json:"description"`
	SpecURI          string `json:"specUri,omitempty"`
	DocumentationURI string `json:"documentationUri,omitempty"`
	Primary          bool   `json:"primary,omitempty"`
}

AuthenticationScheme represents an authentication scheme (RFC 7643 Section 5)

type BulkOperation

type BulkOperation struct {
	Method  string      `json:"method"` // POST, PUT, PATCH, DELETE
	BulkID  string      `json:"bulkId,omitempty"`
	Version string      `json:"version,omitempty"`
	Path    string      `json:"path"`
	Data    interface{} `json:"data,omitempty"`
}

BulkOperation represents a single bulk operation (RFC 7644 Section 3.7)

type BulkOperationResult

type BulkOperationResult struct {
	Method   string      `json:"method"`
	BulkID   string      `json:"bulkId,omitempty"`
	Version  string      `json:"version,omitempty"`
	Location string      `json:"location,omitempty"`
	Status   int         `json:"status"`
	Response interface{} `json:"response,omitempty"`
}

BulkOperationResult represents a single bulk operation result (RFC 7644 Section 3.7)

type BulkOperationsConfig

type BulkOperationsConfig struct {
	Enabled         bool `json:"enabled" yaml:"enabled"`
	MaxOperations   int  `json:"max_operations" yaml:"max_operations"`       // Max operations per bulk request
	MaxPayloadBytes int  `json:"max_payload_bytes" yaml:"max_payload_bytes"` // Max payload size in bytes
}

BulkOperationsConfig configures bulk operation limits

type BulkRequest

type BulkRequest struct {
	Schemas      []string        `json:"schemas"`
	FailOnErrors int             `json:"failOnErrors,omitempty"`
	Operations   []BulkOperation `json:"Operations"`
}

BulkRequest represents a bulk operation request (RFC 7644 Section 3.7)

type BulkResponse

type BulkResponse struct {
	Schemas    []string              `json:"schemas"`
	Operations []BulkOperationResult `json:"Operations"`
}

BulkResponse represents a bulk operation response (RFC 7644 Section 3.7)

type BulkSupport

type BulkSupport struct {
	Supported      bool `json:"supported"`
	MaxOperations  int  `json:"maxOperations"`
	MaxPayloadSize int  `json:"maxPayloadSize"`
}

BulkSupport indicates bulk operation support (RFC 7643 Section 5)

type Config

type Config struct {
	// Service configuration
	Enabled bool `json:"enabled" yaml:"enabled"`

	// Authentication
	AuthMethod  string        `json:"auth_method" yaml:"auth_method"` // "bearer" or "oauth2"
	TokenExpiry time.Duration `json:"token_expiry" yaml:"token_expiry"`

	// Rate limiting
	RateLimit RateLimitConfig `json:"rate_limit" yaml:"rate_limit"`

	// User provisioning
	UserProvisioning UserProvisioningConfig `json:"user_provisioning" yaml:"user_provisioning"`

	// Group synchronization
	GroupSync GroupSyncConfig `json:"group_sync" yaml:"group_sync"`

	// Attribute mapping
	AttributeMapping AttributeMappingConfig `json:"attribute_mapping" yaml:"attribute_mapping"`

	// JIT provisioning
	JITProvisioning JITProvisioningConfig `json:"jit_provisioning" yaml:"jit_provisioning"`

	// Webhooks
	Webhooks WebhookConfig `json:"webhooks" yaml:"webhooks"`

	// Bulk operations
	BulkOperations BulkOperationsConfig `json:"bulk_operations" yaml:"bulk_operations"`

	// Filtering and search
	Search SearchConfig `json:"search" yaml:"search"`

	// Compliance and security
	Security SecurityConfig `json:"security" yaml:"security"`
}

Config holds the SCIM plugin configuration

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns the default SCIM configuration

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration

type ConnectionTestResult added in v0.0.5

type ConnectionTestResult struct {
	Success bool
	Message string
	Details map[string]interface{}
}

ConnectionTestResult holds connection test results

type CreateSCIMProviderRequest added in v0.0.5

type CreateSCIMProviderRequest struct {
	AppID          *xid.ID
	OrganizationID *xid.ID
	Name           string
	Type           string
	Direction      string
	BaseURL        *string
	AuthMethod     string
	TargetURL      *string
	TargetToken    *string
}

CreateSCIMProviderRequest holds data for creating a SCIM provider

type CreateSCIMTokenRequest added in v0.0.5

type CreateSCIMTokenRequest struct {
	AppID          xid.ID
	EnvironmentID  xid.ID
	OrganizationID *xid.ID
	Name           string
	Description    string
	Scopes         []string
	ExpiresAt      *time.Time
}

CreateSCIMTokenRequest holds data for creating a SCIM token

type CreateTokenRequest

type CreateTokenRequest struct {
	Name        string     `json:"name" validate:"required"`
	Description string     `json:"description"`
	Scopes      []string   `json:"scopes" validate:"required,min=1"`
	ExpiresAt   *time.Time `json:"expiresAt"`
}

CreateTokenRequest is the request body for creating a provisioning token

type DashboardExtension added in v0.0.5

type DashboardExtension struct {
	// contains filtered or unexported fields
}

DashboardExtension implements the ui.DashboardExtension interface This allows the SCIM plugin to add its own screens to the dashboard

func NewDashboardExtension added in v0.0.5

func NewDashboardExtension(plugin *Plugin) *DashboardExtension

NewDashboardExtension creates a new dashboard extension for SCIM

func (*DashboardExtension) DashboardWidgets added in v0.0.5

func (e *DashboardExtension) DashboardWidgets() []ui.DashboardWidget

DashboardWidgets returns widgets to show on the main dashboard

func (*DashboardExtension) ExtensionID added in v0.0.5

func (e *DashboardExtension) ExtensionID() string

ExtensionID returns the unique identifier for this extension

func (*DashboardExtension) HandleAddProvider added in v0.0.5

func (e *DashboardExtension) HandleAddProvider(c forge.Context) error

HandleAddProvider handles adding a new provider

func (*DashboardExtension) HandleCreateToken added in v0.0.5

func (e *DashboardExtension) HandleCreateToken(c forge.Context) error

HandleCreateToken handles token creation

func (*DashboardExtension) HandleExportLogs added in v0.0.5

func (e *DashboardExtension) HandleExportLogs(c forge.Context) error

HandleExportLogs handles log export

func (*DashboardExtension) HandleManualSync added in v0.0.5

func (e *DashboardExtension) HandleManualSync(c forge.Context) error

HandleManualSync handles manual sync trigger

func (*DashboardExtension) HandleRemoveProvider added in v0.0.5

func (e *DashboardExtension) HandleRemoveProvider(c forge.Context) error

HandleRemoveProvider handles provider removal

func (*DashboardExtension) HandleRevokeToken added in v0.0.5

func (e *DashboardExtension) HandleRevokeToken(c forge.Context) error

HandleRevokeToken handles token revocation

func (*DashboardExtension) HandleRotateToken added in v0.0.5

func (e *DashboardExtension) HandleRotateToken(c forge.Context) error

HandleRotateToken handles token rotation

func (*DashboardExtension) HandleTestConnection added in v0.0.5

func (e *DashboardExtension) HandleTestConnection(c forge.Context) error

HandleTestConnection handles connection testing

func (*DashboardExtension) HandleTestProvider added in v0.0.5

func (e *DashboardExtension) HandleTestProvider(c forge.Context) error

HandleTestProvider handles provider connection testing

func (*DashboardExtension) HandleUpdateAttributeMapping added in v0.0.5

func (e *DashboardExtension) HandleUpdateAttributeMapping(c forge.Context) error

HandleUpdateAttributeMapping handles attribute mapping update

func (*DashboardExtension) HandleUpdateGroupSync added in v0.0.5

func (e *DashboardExtension) HandleUpdateGroupSync(c forge.Context) error

HandleUpdateGroupSync handles group sync settings update

func (*DashboardExtension) HandleUpdateProvider added in v0.0.5

func (e *DashboardExtension) HandleUpdateProvider(c forge.Context) error

HandleUpdateProvider handles provider updates

func (*DashboardExtension) HandleUpdateSecurity added in v0.0.5

func (e *DashboardExtension) HandleUpdateSecurity(c forge.Context) error

HandleUpdateSecurity handles security settings update

func (*DashboardExtension) HandleUpdateUserProvisioning added in v0.0.5

func (e *DashboardExtension) HandleUpdateUserProvisioning(c forge.Context) error

HandleUpdateUserProvisioning handles user provisioning settings update

func (*DashboardExtension) HandleUpdateWebhooks added in v0.0.5

func (e *DashboardExtension) HandleUpdateWebhooks(c forge.Context) error

HandleUpdateWebhooks handles webhook configuration update

func (*DashboardExtension) NavigationItems added in v0.0.5

func (e *DashboardExtension) NavigationItems() []ui.NavigationItem

NavigationItems returns navigation items to register

func (*DashboardExtension) RenderFailedOperationsWidget added in v0.0.5

func (e *DashboardExtension) RenderFailedOperationsWidget(basePath string, currentApp *app.App) g.Node

RenderFailedOperationsWidget renders the failed operations widget

func (*DashboardExtension) RenderRecentActivityWidget added in v0.0.5

func (e *DashboardExtension) RenderRecentActivityWidget(basePath string, currentApp *app.App) g.Node

RenderRecentActivityWidget renders the recent activity widget

func (*DashboardExtension) RenderSCIMStatusWidget added in v0.0.5

func (e *DashboardExtension) RenderSCIMStatusWidget(basePath string, currentApp *app.App) g.Node

RenderSCIMStatusWidget renders the SCIM status widget for the dashboard

func (*DashboardExtension) RenderSyncStatsWidget added in v0.0.5

func (e *DashboardExtension) RenderSyncStatsWidget(basePath string, currentApp *app.App) g.Node

RenderSyncStatsWidget renders the sync statistics widget

func (*DashboardExtension) Routes added in v0.0.5

func (e *DashboardExtension) Routes() []ui.Route

Routes returns routes to register under /dashboard/app/:appId/

func (*DashboardExtension) ServeConfigPage added in v0.0.5

func (e *DashboardExtension) ServeConfigPage(c forge.Context) error

ServeConfigPage renders the SCIM configuration page

func (*DashboardExtension) ServeLogsPage added in v0.0.5

func (e *DashboardExtension) ServeLogsPage(c forge.Context) error

ServeLogsPage renders the SCIM event logs page

func (*DashboardExtension) ServeMonitoringPage added in v0.0.5

func (e *DashboardExtension) ServeMonitoringPage(c forge.Context) error

ServeMonitoringPage renders the main SCIM monitoring dashboard

func (*DashboardExtension) ServeProviderAddPage added in v0.0.5

func (e *DashboardExtension) ServeProviderAddPage(c forge.Context) error

ServeProviderAddPage renders the add provider page

func (*DashboardExtension) ServeProviderDetailPage added in v0.0.5

func (e *DashboardExtension) ServeProviderDetailPage(c forge.Context) error

ServeProviderDetailPage renders the provider detail page

func (*DashboardExtension) ServeProvidersListPage added in v0.0.5

func (e *DashboardExtension) ServeProvidersListPage(c forge.Context) error

ServeProvidersListPage renders the SCIM providers list page

func (*DashboardExtension) ServeSCIMDashboard added in v0.0.5

func (e *DashboardExtension) ServeSCIMDashboard(c forge.Context) error

func (*DashboardExtension) ServeStatsPage added in v0.0.5

func (e *DashboardExtension) ServeStatsPage(c forge.Context) error

ServeStatsPage renders the SCIM statistics page

func (*DashboardExtension) ServeSyncStatusPage added in v0.0.5

func (e *DashboardExtension) ServeSyncStatusPage(c forge.Context) error

func (*DashboardExtension) ServeTokensListPage added in v0.0.5

func (e *DashboardExtension) ServeTokensListPage(c forge.Context) error

ServeTokensListPage renders the SCIM tokens management page

func (*DashboardExtension) SetRegistry added in v0.0.5

func (e *DashboardExtension) SetRegistry(registry *dashboard.ExtensionRegistry)

SetRegistry sets the extension registry reference (called by dashboard after registration)

func (*DashboardExtension) SettingsPages added in v0.0.5

func (e *DashboardExtension) SettingsPages() []ui.SettingsPage

SettingsPages returns full settings pages for the sidebar layout

func (*DashboardExtension) SettingsSections added in v0.0.5

func (e *DashboardExtension) SettingsSections() []ui.SettingsSection

SettingsSections returns settings sections (deprecated, using SettingsPages instead)

type DashboardStats added in v0.0.5

type DashboardStats struct {
	TotalSyncs     int
	SuccessRate    float64
	FailedSyncs    int
	LastSyncTime   string
	LastSyncStatus string
}

DashboardStats holds statistics for dashboard widgets

type DetailedStats added in v0.0.5

type DetailedStats struct {
	TotalOperations    int
	SuccessRate        float64
	AvgDuration        int64
	TotalErrors        int
	OperationsByType   map[string]int
	OperationsByStatus map[string]int
}

DetailedStats holds detailed statistics for analytics

type Email

type Email struct {
	Value   string `json:"value"`
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"` // work, home, other
	Primary bool   `json:"primary,omitempty"`
}

Email represents an email address (RFC 7643 Section 4.1.2)

type EnterpriseUser

type EnterpriseUser struct {
	EmployeeNumber string            `json:"employeeNumber,omitempty"`
	CostCenter     string            `json:"costCenter,omitempty"`
	Organization   string            `json:"organization,omitempty"`
	Division       string            `json:"division,omitempty"`
	Department     string            `json:"department,omitempty"`
	Manager        *ManagerReference `json:"manager,omitempty"`
}

EnterpriseUser represents enterprise user extension (RFC 7643 Section 4.3)

type Entitlement

type Entitlement struct {
	Value   string `json:"value"`
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"`
	Primary bool   `json:"primary,omitempty"`
}

Entitlement represents an entitlement (RFC 7643 Section 4.1.2)

type ErrorResponse

type ErrorResponse struct {
	Schemas  []string `json:"schemas"`
	Status   int      `json:"status"`
	ScimType string   `json:"scimType,omitempty"` // invalidFilter, tooMany, uniqueness, mutability, invalidSyntax, invalidPath, invalidValue, invalidVers, sensitive, notTarget
	Detail   string   `json:"detail,omitempty"`
}

ErrorResponse represents a SCIM error response (RFC 7644 Section 3.12)

type FilterSupport

type FilterSupport struct {
	Supported  bool `json:"supported"`
	MaxResults int  `json:"maxResults"`
}

FilterSupport indicates filter support (RFC 7643 Section 5)

type GroupMapping

type GroupMapping struct {
	bun.BaseModel  `bun:"table:group_mappings,alias:gm"`
	ID             xid.ID    `bun:"id,pk,type:varchar(20)"`
	AppID          xid.ID    `bun:"app_id,type:varchar(20),notnull"`          // Platform app
	EnvironmentID  xid.ID    `bun:"environment_id,type:varchar(20),notnull"`  // Target environment
	OrganizationID xid.ID    `bun:"organization_id,type:varchar(20),notnull"` // User-created organization
	SCIMGroupID    string    `bun:"scim_group_id,notnull"`
	SCIMGroupName  string    `bun:"scim_group_name,notnull"`
	MappingType    string    `bun:"mapping_type,notnull"`               // team, role (in user-created organization)
	TargetID       xid.ID    `bun:"target_id,type:varchar(20),notnull"` // Team ID or Role ID in user organization
	CreatedAt      time.Time `bun:"created_at,notnull"`
	UpdatedAt      time.Time `bun:"updated_at,notnull"`
}

GroupMapping represents SCIM group to user-created organization team/role mapping Updated for 3-tier architecture: App → Environment → Organization

type GroupReference

type GroupReference struct {
	Value   string `json:"value"` // Group ID
	Ref     string `json:"$ref,omitempty"`
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"` // direct, indirect
}

GroupReference represents a group membership (RFC 7643 Section 4.1.2)

type GroupSyncConfig

type GroupSyncConfig struct {
	Enabled             bool              `json:"enabled" yaml:"enabled"`
	SyncToTeams         bool              `json:"sync_to_teams" yaml:"sync_to_teams"`                 // Sync SCIM groups to teams
	SyncToRoles         bool              `json:"sync_to_roles" yaml:"sync_to_roles"`                 // Sync SCIM groups to roles
	GroupMapping        map[string]string `json:"group_mapping" yaml:"group_mapping"`                 // Map SCIM group ID to team/role ID
	CreateMissingGroups bool              `json:"create_missing_groups" yaml:"create_missing_groups"` // Auto-create teams/roles
	DeleteEmptyGroups   bool              `json:"delete_empty_groups" yaml:"delete_empty_groups"`     // Delete teams/roles with no members
}

GroupSyncConfig configures group synchronization with teams/roles

type GroupsResponse

type GroupsResponse struct {
	Groups []SCIMGroup `json:"groups"`
	Total  int         `json:"total"`
}

GroupsResponse wraps group list response for clarity

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler handles SCIM HTTP requests

func NewHandler

func NewHandler(service *Service, config *Config) *Handler

NewHandler creates a new SCIM handler

func (*Handler) BulkOperation

func (h *Handler) BulkOperation(c forge.Context) error

BulkOperation handles bulk operations

func (*Handler) CreateGroup

func (h *Handler) CreateGroup(c forge.Context) error

CreateGroup creates a new group

func (*Handler) CreateProvisioningToken

func (h *Handler) CreateProvisioningToken(c forge.Context) error

CreateProvisioningToken creates a new provisioning token

func (*Handler) CreateUser

func (h *Handler) CreateUser(c forge.Context) error

CreateUser creates a new user

Example

Example: SCIM User creation request

package main

import ()

func main() {
	// POST /scim/v2/Users
	// Authorization: Bearer <token>
	// Content-Type: application/scim+json
	//
	// {
	//   "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
	//   "userName": "bjensen@example.com",
	//   "name": {
	//     "givenName": "Barbara",
	//     "familyName": "Jensen"
	//   },
	//   "emails": [{
	//     "value": "bjensen@example.com",
	//     "type": "work",
	//     "primary": true
	//   }],
	//   "active": true
	// }
}

func (*Handler) DeleteGroup

func (h *Handler) DeleteGroup(c forge.Context) error

DeleteGroup deletes a group

func (*Handler) DeleteUser

func (h *Handler) DeleteUser(c forge.Context) error

DeleteUser deletes a user

func (*Handler) GetAttributeMappings

func (h *Handler) GetAttributeMappings(c forge.Context) error

GetAttributeMappings gets attribute mappings

func (*Handler) GetGroup

func (h *Handler) GetGroup(c forge.Context) error

GetGroup retrieves a specific group

func (*Handler) GetProvisioningLogs

func (h *Handler) GetProvisioningLogs(c forge.Context) error

GetProvisioningLogs gets provisioning logs

func (*Handler) GetProvisioningStats

func (h *Handler) GetProvisioningStats(c forge.Context) error

GetProvisioningStats gets provisioning statistics

func (*Handler) GetResourceType

func (h *Handler) GetResourceType(c forge.Context) error

GetResourceType returns a specific resource type

func (*Handler) GetResourceTypes

func (h *Handler) GetResourceTypes(c forge.Context) error

GetResourceTypes returns all supported resource types

func (*Handler) GetSchema

func (h *Handler) GetSchema(c forge.Context) error

GetSchema returns a specific schema

func (*Handler) GetSchemas

func (h *Handler) GetSchemas(c forge.Context) error

GetSchemas returns all supported schemas

func (*Handler) GetServiceProviderConfig

func (h *Handler) GetServiceProviderConfig(c forge.Context) error

GetServiceProviderConfig returns the service provider configuration

func (*Handler) GetUser

func (h *Handler) GetUser(c forge.Context) error

GetUser retrieves a specific user

func (*Handler) ListGroups

func (h *Handler) ListGroups(c forge.Context) error

ListGroups lists groups

func (*Handler) ListProvisioningTokens

func (h *Handler) ListProvisioningTokens(c forge.Context) error

ListProvisioningTokens lists provisioning tokens

func (*Handler) ListUsers

func (h *Handler) ListUsers(c forge.Context) error

ListUsers lists users with filtering and pagination

func (*Handler) ReplaceGroup

func (h *Handler) ReplaceGroup(c forge.Context) error

ReplaceGroup replaces a group (PUT)

func (*Handler) ReplaceUser

func (h *Handler) ReplaceUser(c forge.Context) error

ReplaceUser replaces a user (PUT)

func (*Handler) RevokeProvisioningToken

func (h *Handler) RevokeProvisioningToken(c forge.Context) error

RevokeProvisioningToken revokes a provisioning token

func (*Handler) Search

func (h *Handler) Search(c forge.Context) error

Search handles the /.search endpoint

func (*Handler) UpdateAttributeMappings

func (h *Handler) UpdateAttributeMappings(c forge.Context) error

UpdateAttributeMappings updates attribute mappings

func (*Handler) UpdateGroup

func (h *Handler) UpdateGroup(c forge.Context) error

UpdateGroup updates a group (PATCH)

func (*Handler) UpdateUser

func (h *Handler) UpdateUser(c forge.Context) error

UpdateUser updates a user (PATCH)

type IM

type IM struct {
	Value   string `json:"value"`
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"` // aim, gtalk, icq, xmpp, msn, skype, qq, yahoo
	Primary bool   `json:"primary,omitempty"`
}

IM represents an instant messaging address (RFC 7643 Section 4.1.2)

type JITProvisioningConfig

type JITProvisioningConfig struct {
	Enabled            bool     `json:"enabled" yaml:"enabled"`
	CreateOnFirstLogin bool     `json:"create_on_first_login" yaml:"create_on_first_login"` // Create user on first SSO login
	UpdateOnLogin      bool     `json:"update_on_login" yaml:"update_on_login"`             // Update user attributes on each login
	RequiredAttributes []string `json:"required_attributes" yaml:"required_attributes"`
}

JITProvisioningConfig configures Just-In-Time provisioning

type ListResponse

type ListResponse struct {
	Schemas      []string      `json:"schemas"`
	TotalResults int           `json:"totalResults"`
	StartIndex   int           `json:"startIndex"`
	ItemsPerPage int           `json:"itemsPerPage"`
	Resources    []interface{} `json:"Resources"`
}

ListResponse represents a SCIM list response (RFC 7644 Section 3.4.2)

type LogsResponse

type LogsResponse struct {
	Logs  []ProvisioningLog `json:"logs"`
	Total int               `json:"total"`
	Page  int               `json:"page"`
	Limit int               `json:"limit"`
}

LogsResponse represents a list of provisioning logs

type ManagerReference

type ManagerReference struct {
	Value       string `json:"value"` // Manager's ID
	Ref         string `json:"$ref,omitempty"`
	DisplayName string `json:"displayName,omitempty"`
}

ManagerReference represents a manager reference (RFC 7643 Section 4.3.1)

type MemberReference

type MemberReference struct {
	Value   string `json:"value"` // User ID
	Ref     string `json:"$ref,omitempty"`
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"` // User or Group
}

MemberReference represents a group member (RFC 7643 Section 4.2)

type MessageResponse

type MessageResponse = responses.MessageResponse

Response types - use shared responses from core

type Metrics

type Metrics struct {
	// contains filtered or unexported fields
}

Metrics collects SCIM plugin metrics using Go's built-in expvar These metrics are automatically exposed via the /debug/vars endpoint

func GetMetrics

func GetMetrics() *Metrics

GetMetrics returns the singleton metrics instance

func (*Metrics) DecrementActiveRequests

func (m *Metrics) DecrementActiveRequests()

DecrementActiveRequests decrements the active request counter

func (*Metrics) GetStats

func (m *Metrics) GetStats() map[string]interface{}

GetStats returns current statistics

func (*Metrics) IncrementActiveRequests

func (m *Metrics) IncrementActiveRequests()

IncrementActiveRequests increments the active request counter

func (*Metrics) RecordBulkOperation

func (m *Metrics) RecordBulkOperation(operationCount int)

RecordBulkOperation records a bulk operation

func (*Metrics) RecordError

func (m *Metrics) RecordError(errorType string)

RecordError records an error by type

func (*Metrics) RecordGroupOperation

func (m *Metrics) RecordGroupOperation(operation string)

RecordGroupOperation records a group operation

func (*Metrics) RecordOperation

func (m *Metrics) RecordOperation(operation, status, orgID string)

RecordOperation records a SCIM operation

func (*Metrics) RecordRateLimitHit

func (m *Metrics) RecordRateLimitHit()

RecordRateLimitHit records a rate limit hit

func (*Metrics) RecordRequestDuration

func (m *Metrics) RecordRequestDuration(endpoint string, duration time.Duration)

RecordRequestDuration records the duration of a SCIM request

func (*Metrics) RecordTokenCreation

func (m *Metrics) RecordTokenCreation()

RecordTokenCreation records a token creation

func (*Metrics) RecordTokenRevocation

func (m *Metrics) RecordTokenRevocation()

RecordTokenRevocation records a token revocation

func (*Metrics) RecordTokenValidation

func (m *Metrics) RecordTokenValidation(success bool)

RecordTokenValidation records a token validation attempt

func (*Metrics) RecordUserOperation

func (m *Metrics) RecordUserOperation(operation string)

RecordUserOperation records a user provisioning operation

func (*Metrics) RecordWebhook

func (m *Metrics) RecordWebhook(success bool, retried bool)

RecordWebhook records a webhook operation

func (*Metrics) Reset

func (m *Metrics) Reset()

Reset resets all metrics (useful for testing)

type OrganizationUIExtension added in v0.0.5

type OrganizationUIExtension struct {
	// contains filtered or unexported fields
}

OrganizationUIExtension implements ui.OrganizationUIExtension to extend organization pages

func NewOrganizationUIExtension added in v0.0.5

func NewOrganizationUIExtension(plugin *Plugin) *OrganizationUIExtension

NewOrganizationUIExtension creates a new organization UI extension

func (*OrganizationUIExtension) ExtensionID added in v0.0.5

func (e *OrganizationUIExtension) ExtensionID() string

ExtensionID returns the unique identifier for this extension

func (*OrganizationUIExtension) OrganizationActions added in v0.0.5

func (e *OrganizationUIExtension) OrganizationActions() []ui.OrganizationAction

OrganizationActions returns action buttons for the organization header

func (e *OrganizationUIExtension) OrganizationQuickLinks() []ui.OrganizationQuickLink

OrganizationQuickLinks returns quick access cards

func (*OrganizationUIExtension) OrganizationSettingsSections added in v0.0.5

func (e *OrganizationUIExtension) OrganizationSettingsSections() []ui.OrganizationSettingsSection

OrganizationSettingsSections returns settings sections for org settings

func (*OrganizationUIExtension) OrganizationTabs added in v0.0.5

func (e *OrganizationUIExtension) OrganizationTabs() []ui.OrganizationTab

OrganizationTabs returns full-page tabs for organization content

func (*OrganizationUIExtension) OrganizationWidgets added in v0.0.5

func (e *OrganizationUIExtension) OrganizationWidgets() []ui.OrganizationWidget

OrganizationWidgets returns widgets for the organization detail page

type PatchOp

type PatchOp struct {
	Schemas    []string         `json:"schemas"`
	Operations []PatchOperation `json:"Operations"`
}

PatchOp represents a PATCH operation (RFC 7644 Section 3.5.2)

type PatchOperation

type PatchOperation struct {
	Op    string      `json:"op"` // add, remove, replace
	Path  string      `json:"path,omitempty"`
	Value interface{} `json:"value,omitempty"`
}

PatchOperation represents a single patch operation (RFC 7644 Section 3.5.2)

type PhoneNumber

type PhoneNumber struct {
	Value   string `json:"value"`
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"` // work, home, mobile, fax, pager, other
	Primary bool   `json:"primary,omitempty"`
}

PhoneNumber represents a phone number (RFC 7643 Section 4.1.2)

type Photo

type Photo struct {
	Value   string `json:"value"`
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"` // photo, thumbnail
	Primary bool   `json:"primary,omitempty"`
}

Photo represents a photo URL (RFC 7643 Section 4.1.2)

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin implements the SCIM 2.0 provisioning plugin for enterprise identity providers

Example (Basic)

Example: Basic SCIM plugin integration

package main

import (
	"context"

	"github.com/xraph/authsome"
	"github.com/xraph/authsome/plugins/enterprise/scim"
)

func main() {
	// Create AuthSome instance
	auth := authsome.New(
	// Configure with valid options
	)

	// Register SCIM plugin
	scimPlugin := scim.NewPlugin()
	auth.RegisterPlugin(scimPlugin)

	// Initialize (runs migrations)
	ctx := context.Background()
	auth.Initialize(ctx)

	// Mount routes
	// auth.Mount(router, "/api/auth")

	// SCIM endpoints are now available at:
	// - /api/auth/scim/v2/Users
	// - /api/auth/scim/v2/Groups
	// - /api/auth/scim/v2/Bulk
}

func NewPlugin

func NewPlugin(opts ...PluginOption) *Plugin

NewPlugin creates a new SCIM plugin instance

func (*Plugin) AuthMiddleware

func (p *Plugin) AuthMiddleware() func(func(forge.Context) error) func(forge.Context) error

AuthMiddleware validates SCIM bearer tokens

func (*Plugin) DashboardExtension added in v0.0.5

func (p *Plugin) DashboardExtension() ui.DashboardExtension

DashboardExtension returns the dashboard extension for the SCIM plugin This allows the plugin to extend the dashboard with SCIM-specific UI This implements the PluginWithDashboardExtension interface

func (*Plugin) Description

func (p *Plugin) Description() string

Description returns the plugin description (optional, for documentation)

func (*Plugin) ExtensionID added in v0.0.5

func (p *Plugin) ExtensionID() string

func (*Plugin) Health

func (p *Plugin) Health(ctx context.Context) error

Health checks plugin health

func (*Plugin) ID

func (p *Plugin) ID() string

ID returns the unique plugin identifier

func (*Plugin) IPWhitelistMiddleware

func (p *Plugin) IPWhitelistMiddleware() func(func(forge.Context) error) func(forge.Context) error

IPWhitelistMiddleware enforces IP whitelisting if configured

func (*Plugin) Init

func (p *Plugin) Init(auth core.Authsome) error

Init initializes the plugin with dependencies from the Auth instance

func (*Plugin) LoggingMiddleware

func (p *Plugin) LoggingMiddleware() func(func(forge.Context) error) func(forge.Context) error

LoggingMiddleware logs SCIM operations for audit

func (*Plugin) Migrate

func (p *Plugin) Migrate() error

Migrate runs database migrations for SCIM-specific tables

func (*Plugin) Name

func (p *Plugin) Name() string

Name returns the human-readable plugin name (optional, for dashboard display)

func (*Plugin) OrgResolutionMiddleware

func (p *Plugin) OrgResolutionMiddleware() func(func(forge.Context) error) func(forge.Context) error

OrgResolutionMiddleware ensures organization context is set (3-tier architecture)

func (*Plugin) OrganizationActions added in v0.0.5

func (p *Plugin) OrganizationActions() []ui.OrganizationAction
func (p *Plugin) OrganizationQuickLinks() []ui.OrganizationQuickLink

func (*Plugin) OrganizationSettingsSections added in v0.0.5

func (p *Plugin) OrganizationSettingsSections() []ui.OrganizationSettingsSection

func (*Plugin) OrganizationTabs added in v0.0.5

func (p *Plugin) OrganizationTabs() []ui.OrganizationTab

func (*Plugin) OrganizationWidgets added in v0.0.5

func (p *Plugin) OrganizationWidgets() []ui.OrganizationWidget

func (*Plugin) RateLimitMiddleware

func (p *Plugin) RateLimitMiddleware() func(func(forge.Context) error) func(forge.Context) error

RateLimitMiddleware implements rate limiting for SCIM endpoints

func (*Plugin) RegisterHooks

func (p *Plugin) RegisterHooks(hooks *hooks.HookRegistry) error

RegisterHooks registers lifecycle hooks for SCIM events

func (*Plugin) RegisterRoutes

func (p *Plugin) RegisterRoutes(router forge.Router) error

RegisterRoutes registers SCIM 2.0 compliant HTTP routes

func (*Plugin) RegisterServiceDecorators

func (p *Plugin) RegisterServiceDecorators(services *registry.ServiceRegistry) error

RegisterServiceDecorators allows SCIM plugin to enhance core services

func (*Plugin) RequireAdminMiddleware

func (p *Plugin) RequireAdminMiddleware() func(func(forge.Context) error) func(forge.Context) error

RequireAdminMiddleware ensures the request is from an admin

func (*Plugin) SecurityHeadersMiddleware

func (p *Plugin) SecurityHeadersMiddleware() func(func(forge.Context) error) func(forge.Context) error

SecurityHeadersMiddleware adds security headers to SCIM responses

func (*Plugin) Service

func (p *Plugin) Service() *Service

Service returns the SCIM service for programmatic access

func (*Plugin) Shutdown

func (p *Plugin) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the plugin

func (*Plugin) Version

func (p *Plugin) Version() string

Version returns the plugin version (optional, for compatibility checks)

type PluginOption added in v0.0.5

type PluginOption func(*Plugin)

PluginOption is a functional option for configuring the SCIM plugin

func WithAuthMethod added in v0.0.5

func WithAuthMethod(method string) PluginOption

WithAuthMethod sets the authentication method (bearer or oauth2)

func WithBulkOperations added in v0.0.5

func WithBulkOperations(enabled bool, maxOps, maxPayloadBytes int) PluginOption

WithBulkOperations configures bulk operation limits

func WithDefaultConfig added in v0.0.5

func WithDefaultConfig(cfg *Config) PluginOption

WithDefaultConfig sets the default configuration for the plugin

func WithGroupSync added in v0.0.5

func WithGroupSync(enabled, syncToTeams, syncToRoles, createMissing bool) PluginOption

WithGroupSync configures group synchronization

func WithJITProvisioning added in v0.0.5

func WithJITProvisioning(enabled, createOnFirstLogin, updateOnLogin bool) PluginOption

WithJITProvisioning configures Just-In-Time provisioning

func WithRateLimit added in v0.0.5

func WithRateLimit(enabled bool, requestsPerMin, burstSize int) PluginOption

WithRateLimit configures rate limiting

func WithSecurity added in v0.0.5

func WithSecurity(requireHTTPS, auditAll, maskSensitive bool, ipWhitelist []string) PluginOption

WithSecurity configures security settings

func WithUserProvisioning added in v0.0.5

func WithUserProvisioning(autoActivate, sendWelcomeEmail, preventDuplicates bool, defaultRole string) PluginOption

WithUserProvisioning configures user provisioning behavior

func WithWebhooks added in v0.0.5

func WithWebhooks(enabled bool, urls []string, retryAttempts int) PluginOption

WithWebhooks configures provisioning event webhooks

type ProviderHealth added in v0.0.5

type ProviderHealth struct {
	Healthy      bool
	Status       string
	LastCheck    time.Time
	ResponseTime int64 // milliseconds
	ErrorMessage string
}

ProviderHealth holds provider health status

type ProviderStats added in v0.0.5

type ProviderStats struct {
	TotalProviders  int
	ActiveProviders int
}

ProviderStats holds provider statistics

type ProvisioningLog

type ProvisioningLog struct {
	ID             xid.ID                 `bun:"id,pk,type:varchar(20)"`
	AppID          xid.ID                 `bun:"app_id,type:varchar(20),notnull"`          // Platform app
	EnvironmentID  xid.ID                 `bun:"environment_id,type:varchar(20),notnull"`  // Target environment
	OrganizationID xid.ID                 `bun:"organization_id,type:varchar(20),notnull"` // User-created organization
	TokenID        xid.ID                 `bun:"token_id,type:varchar(20)"`
	Operation      string                 `bun:"operation,notnull"`     // CREATE_USER, UPDATE_USER, DELETE_USER, etc.
	ResourceType   string                 `bun:"resource_type,notnull"` // User, Group
	ResourceID     string                 `bun:"resource_id"`
	ExternalID     string                 `bun:"external_id"`
	Method         string                 `bun:"method,notnull"` // POST, PUT, PATCH, DELETE
	Path           string                 `bun:"path,notnull"`
	StatusCode     int                    `bun:"status_code,notnull"`
	Success        bool                   `bun:"success,notnull"`
	ErrorMessage   string                 `bun:"error_message"`
	RequestBody    map[string]interface{} `bun:"request_body,type:jsonb"`
	ResponseBody   map[string]interface{} `bun:"response_body,type:jsonb"`
	IPAddress      string                 `bun:"ip_address"`
	UserAgent      string                 `bun:"user_agent"`
	DurationMS     int                    `bun:"duration_ms"`
	CreatedAt      time.Time              `bun:"created_at,notnull"`
}

ProvisioningLog represents a log entry for provisioning operations Updated for 3-tier architecture: App → Environment → Organization

type ProvisioningToken

type ProvisioningToken struct {
	ID             xid.ID     `bun:"id,pk,type:varchar(20)"`
	AppID          xid.ID     `bun:"app_id,type:varchar(20),notnull"`          // Platform app
	EnvironmentID  xid.ID     `bun:"environment_id,type:varchar(20),notnull"`  // Target environment (dev, prod, etc.)
	OrganizationID xid.ID     `bun:"organization_id,type:varchar(20),notnull"` // User-created organization
	Name           string     `bun:"name,notnull"`
	Description    string     `bun:"description"`
	TokenHash      string     `bun:"token_hash,notnull,unique"` // bcrypt hash
	TokenPrefix    string     `bun:"token_prefix,notnull"`      // First 8 chars for identification
	Scopes         []string   `bun:"scopes,type:text[],notnull"`
	ExpiresAt      *time.Time `bun:"expires_at"`
	LastUsedAt     *time.Time `bun:"last_used_at"`
	CreatedBy      xid.ID     `bun:"created_by,type:varchar(20)"`
	CreatedAt      time.Time  `bun:"created_at,notnull"`
	UpdatedAt      time.Time  `bun:"updated_at,notnull"`
	RevokedAt      *time.Time `bun:"revoked_at"`
}

ProvisioningToken represents a SCIM provisioning token (Bearer token) Updated for 3-tier architecture: App → Environment → Organization

type ProvisioningTokenInfo

type ProvisioningTokenInfo struct {
	ID          string     `json:"id"`
	Name        string     `json:"name"`
	Description string     `json:"description"`
	Scopes      []string   `json:"scopes"`
	ExpiresAt   *time.Time `json:"expiresAt"`
	LastUsedAt  *time.Time `json:"lastUsedAt"`
	CreatedAt   time.Time  `json:"createdAt"`
	RevokedAt   *time.Time `json:"revokedAt,omitempty"`
}

ProvisioningTokenInfo contains token metadata without the actual token

type RateLimitConfig

type RateLimitConfig struct {
	Enabled        bool `json:"enabled" yaml:"enabled"`
	RequestsPerMin int  `json:"requests_per_min" yaml:"requests_per_min"`
	BurstSize      int  `json:"burst_size" yaml:"burst_size"`
}

RateLimitConfig configures rate limiting for SCIM endpoints

type Repository

type Repository struct {
	// contains filtered or unexported fields
}

Repository handles SCIM data persistence

func NewRepository

func NewRepository(db *bun.DB) *Repository

NewRepository creates a new SCIM repository

func (*Repository) CountProvisioningLogs

func (r *Repository) CountProvisioningLogs(ctx context.Context, appID, envID, orgID xid.ID, filters map[string]interface{}) (int, error)

CountProvisioningLogs counts provisioning logs with filtering

func (*Repository) CountProvisioningTokens

func (r *Repository) CountProvisioningTokens(ctx context.Context, appID, envID, orgID xid.ID) (int, error)

CountProvisioningTokens counts active tokens for an organization Updated for 3-tier architecture

func (*Repository) CreateAttributeMapping

func (r *Repository) CreateAttributeMapping(ctx context.Context, mapping *AttributeMapping) error

CreateAttributeMapping creates a new attribute mapping

func (*Repository) CreateGroupMapping

func (r *Repository) CreateGroupMapping(ctx context.Context, mapping *GroupMapping) error

CreateGroupMapping creates a new group mapping

func (*Repository) CreateProvisioningLog

func (r *Repository) CreateProvisioningLog(ctx context.Context, log *ProvisioningLog) error

CreateProvisioningLog creates a new provisioning log entry

func (*Repository) CreateProvisioningToken

func (r *Repository) CreateProvisioningToken(ctx context.Context, token *ProvisioningToken) error

CreateProvisioningToken creates a new provisioning token

func (*Repository) DeleteGroupMapping

func (r *Repository) DeleteGroupMapping(ctx context.Context, id xid.ID) error

DeleteGroupMapping deletes a group mapping

func (*Repository) FindAttributeMappingByOrganization

func (r *Repository) FindAttributeMappingByOrganization(ctx context.Context, appID, envID, orgID xid.ID) (*AttributeMapping, error)

FindAttributeMappingByOrgID finds attribute mapping by organization ID

func (*Repository) FindGroupMapping

func (r *Repository) FindGroupMapping(ctx context.Context, appID, envID, orgID xid.ID, scimGroupID string) (*GroupMapping, error)

FindGroupMapping finds a group mapping by SCIM group ID

func (*Repository) FindGroupMappingBySCIMID

func (r *Repository) FindGroupMappingBySCIMID(ctx context.Context, appID, envID, orgID xid.ID, scimGroupID string) (*GroupMapping, error)

FindGroupMappingBySCIMID finds a group mapping by SCIM group ID Updated for 3-tier architecture

func (*Repository) FindGroupMappingByTargetID

func (r *Repository) FindGroupMappingByTargetID(ctx context.Context, targetID xid.ID) (*GroupMapping, error)

FindGroupMappingByTargetID finds a group mapping by target team ID

func (*Repository) FindProvisioningTokenByID

func (r *Repository) FindProvisioningTokenByID(ctx context.Context, id xid.ID) (*ProvisioningToken, error)

FindProvisioningTokenByID finds a token by ID

func (*Repository) FindProvisioningTokenByPrefix

func (r *Repository) FindProvisioningTokenByPrefix(ctx context.Context, prefix string) (*ProvisioningToken, error)

FindProvisioningTokenByPrefix finds a token by its prefix

func (*Repository) GetAttributeMapping

func (r *Repository) GetAttributeMapping(ctx context.Context, appID, envID, orgID xid.ID) (*AttributeMapping, error)

GetAttributeMapping gets attribute mapping for an organization

func (*Repository) GetProvisioningStats

func (r *Repository) GetProvisioningStats(ctx context.Context, appID, envID, orgID xid.ID, startDate, endDate time.Time) (map[string]interface{}, error)

GetProvisioningStats returns provisioning statistics

func (*Repository) ListGroupMappings

func (r *Repository) ListGroupMappings(ctx context.Context, appID, envID, orgID xid.ID) ([]*GroupMapping, error)

ListGroupMappings lists all group mappings for an organization

func (*Repository) ListProvisioningLogs

func (r *Repository) ListProvisioningLogs(ctx context.Context, appID, envID, orgID xid.ID, filters map[string]interface{}, limit, offset int) ([]*ProvisioningLog, error)

ListProvisioningLogs lists provisioning logs with filtering Updated for 3-tier architecture

func (*Repository) ListProvisioningTokens

func (r *Repository) ListProvisioningTokens(ctx context.Context, appID, envID, orgID xid.ID, limit, offset int) ([]*ProvisioningToken, error)

ListProvisioningTokens lists all provisioning tokens for an organization Updated for 3-tier architecture: App → Environment → Organization

func (*Repository) Migrate

func (r *Repository) Migrate(ctx context.Context) error

Migrate runs database migrations

func (*Repository) Ping

func (r *Repository) Ping(ctx context.Context) error

Ping checks database connectivity

func (*Repository) RevokeProvisioningToken

func (r *Repository) RevokeProvisioningToken(ctx context.Context, id xid.ID) error

RevokeProvisioningToken revokes a provisioning token

func (*Repository) UpdateAttributeMapping

func (r *Repository) UpdateAttributeMapping(ctx context.Context, mapping *AttributeMapping) error

UpdateAttributeMapping updates attribute mapping

func (*Repository) UpdateGroupMapping

func (r *Repository) UpdateGroupMapping(ctx context.Context, mapping *GroupMapping) error

UpdateGroupMapping updates a group mapping

func (*Repository) UpdateProvisioningToken

func (r *Repository) UpdateProvisioningToken(ctx context.Context, token *ProvisioningToken) error

UpdateProvisioningToken updates a provisioning token

func (*Repository) UpdateTeamMemberProvisioningInfo added in v0.0.2

func (r *Repository) UpdateTeamMemberProvisioningInfo(ctx context.Context, teamID, memberID xid.ID, provisionedBy *string) error

UpdateTeamMemberProvisioningInfo updates team member provisioning tracking field This method updates both app team members and organization team members

func (*Repository) UpdateTeamProvisioningInfo added in v0.0.2

func (r *Repository) UpdateTeamProvisioningInfo(ctx context.Context, teamID xid.ID, provisionedBy, externalID *string) error

UpdateTeamProvisioningInfo updates team provisioning tracking fields This method updates both app teams and organization teams

type ResourceType

type ResourceType struct {
	Schemas          []string          `json:"schemas"`
	ID               string            `json:"id"`
	Name             string            `json:"name"`
	Endpoint         string            `json:"endpoint"`
	Description      string            `json:"description,omitempty"`
	Schema           string            `json:"schema"`
	SchemaExtensions []SchemaExtension `json:"schemaExtensions,omitempty"`
	Meta             *SCIMMeta         `json:"meta"`
}

ResourceType represents a resource type (RFC 7643 Section 6)

type SCIMAddress added in v0.0.5

type SCIMAddress struct {
	Formatted     string `json:"formatted,omitempty"`
	StreetAddress string `json:"streetAddress,omitempty"`
	Locality      string `json:"locality,omitempty"`
	Region        string `json:"region,omitempty"`
	PostalCode    string `json:"postalCode,omitempty"`
	Country       string `json:"country,omitempty"`
	Type          string `json:"type,omitempty"` // work, home, other
	Primary       bool   `json:"primary,omitempty"`
}

SCIMAddress represents a physical mailing address (RFC 7643 Section 4.1.2)

type SCIMAttributeMappingsResponse

type SCIMAttributeMappingsResponse struct {
	Mappings map[string]string `json:"mappings" example:"userName:email,displayName:name"`
}

SCIMAttributeMappingsResponse represents attribute mappings response

type SCIMErrorResponse

type SCIMErrorResponse struct {
	Error string `json:"error" example:"Error message"`
}

SCIMErrorResponse represents an error response for admin endpoints

type SCIMGroup

type SCIMGroup struct {
	Schemas     []string          `json:"schemas"`
	ID          string            `json:"id"`
	ExternalID  string            `json:"externalId,omitempty"`
	Meta        *SCIMMeta         `json:"meta"`
	DisplayName string            `json:"displayName"`
	Members     []MemberReference `json:"members,omitempty"`
}

SCIMGroup represents a SCIM 2.0 Group resource (RFC 7643 Section 4.2)

type SCIMLogInfo

type SCIMLogInfo struct {
	ID           string    `json:"id" example:"01HZ..."`
	Operation    string    `json:"operation" example:"CREATE_USER"`
	ResourceType string    `json:"resource_type" example:"User"`
	ResourceID   string    `json:"resource_id" example:"01HZ..."`
	Method       string    `json:"method" example:"POST"`
	Path         string    `json:"path" example:"/scim/v2/Users"`
	StatusCode   int       `json:"status_code" example:"201"`
	Success      bool      `json:"success" example:"true"`
	ErrorMessage string    `json:"error_message"`
	CreatedAt    time.Time `json:"created_at"`
	DurationMS   int       `json:"duration_ms" example:"45"`
}

SCIMLogInfo represents a single log entry

type SCIMLogsResponse

type SCIMLogsResponse struct {
	Logs   []SCIMLogInfo `json:"logs"`
	Total  int           `json:"total" example:"100"`
	Limit  int           `json:"limit" example:"50"`
	Offset int           `json:"offset" example:"0"`
}

SCIMLogsResponse represents provisioning logs response

type SCIMMeta added in v0.0.5

type SCIMMeta struct {
	ResourceType string    `json:"resourceType"`
	Created      time.Time `json:"created"`
	LastModified time.Time `json:"lastModified"`
	Location     string    `json:"location"`
	Version      string    `json:"version,omitempty"`
}

SCIMMeta contains resource metadata (RFC 7643 Section 3.1)

type SCIMName added in v0.0.5

type SCIMName struct {
	Formatted       string `json:"formatted,omitempty"`
	FamilyName      string `json:"familyName,omitempty"`
	GivenName       string `json:"givenName,omitempty"`
	MiddleName      string `json:"middleName,omitempty"`
	HonorificPrefix string `json:"honorificPrefix,omitempty"`
	HonorificSuffix string `json:"honorificSuffix,omitempty"`
}

SCIMName represents a user's name (RFC 7643 Section 4.1.1)

type SCIMOrgService

type SCIMOrgService interface {
	// Member operations
	AddMember(ctx context.Context, orgID, userID xid.ID, role string) (interface{}, error)
	IsUserMember(ctx context.Context, orgID, userID xid.ID) (bool, error)
	ListMembers(ctx context.Context, orgID xid.ID, limit, offset int) ([]interface{}, error)

	// Team operations
	CreateTeam(ctx context.Context, orgID xid.ID, req interface{}) (interface{}, error)
	GetTeam(ctx context.Context, id xid.ID) (interface{}, error)
	ListTeams(ctx context.Context, orgID xid.ID, limit, offset int) ([]interface{}, error)
	UpdateTeam(ctx context.Context, id xid.ID, req interface{}) (interface{}, error)
	DeleteTeam(ctx context.Context, id xid.ID) error
	AddTeamMember(ctx context.Context, teamID, memberID xid.ID, role string) error
	RemoveTeamMember(ctx context.Context, teamID, memberID xid.ID) error
	ListTeamMembers(ctx context.Context, teamID xid.ID) ([]interface{}, error)

	// Get member ID from user ID (for team operations)
	GetMemberIDByUserID(ctx context.Context, orgID, userID xid.ID) (xid.ID, error)
}

SCIMOrgService defines a unified interface for organization/app operations Supports both app mode (multitenancy) and organization mode (organization plugin)

type SCIMProvider added in v0.0.5

type SCIMProvider = schema.SCIMProvider

SCIMProvider represents a SCIM identity provider (imported from schema)

type SCIMProviderInfo added in v0.0.5

type SCIMProviderInfo struct {
	ID           string
	Name         string
	Type         string
	Endpoint     string
	Enabled      bool
	LastSyncTime string
}

type SCIMRole added in v0.0.5

type SCIMRole struct {
	Value   string `json:"value"`
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"`
	Primary bool   `json:"primary,omitempty"`
}

SCIMRole represents a role (RFC 7643 Section 4.1.2)

type SCIMStatsResponse

type SCIMStatsResponse struct {
	SCIMMetrics map[string]interface{} `json:"scim_metrics"`
}

SCIMStatsResponse represents provisioning statistics response

type SCIMStatusResponse

type SCIMStatusResponse struct {
	Message string `json:"message" example:"Operation successful"`
}

SCIMStatusResponse represents a status response

type SCIMSyncEvent added in v0.0.5

type SCIMSyncEvent = schema.SCIMSyncEvent

SCIMSyncEvent represents a sync event (imported from schema)

type SCIMToken added in v0.0.5

type SCIMToken struct {
	ID             xid.ID     `json:"id"`
	AppID          xid.ID     `json:"app_id"`
	EnvironmentID  xid.ID     `json:"environment_id"`
	OrganizationID *xid.ID    `json:"organization_id,omitempty"`
	Name           string     `json:"name"`
	Description    string     `json:"description"`
	Token          string     `json:"token,omitempty"` // Only populated on creation
	Scopes         []string   `json:"scopes"`
	ExpiresAt      *time.Time `json:"expires_at,omitempty"`
	RevokedAt      *time.Time `json:"revoked_at,omitempty"`
	LastUsedAt     *time.Time `json:"last_used_at,omitempty"`
	UsageCount     int64      `json:"usage_count"`
	CreatedAt      time.Time  `json:"created_at"`
	UpdatedAt      time.Time  `json:"updated_at"`
}

SCIMToken represents a SCIM bearer token for authentication

type SCIMTokenInfo

type SCIMTokenInfo struct {
	ID          string     `json:"id" example:"01HZ..."`
	Name        string     `json:"name" example:"Production SCIM Token"`
	Description string     `json:"description" example:"Token for Okta provisioning"`
	Scopes      []string   `json:"scopes" example:"users,groups"`
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
	LastUsedAt  *time.Time `json:"last_used_at"`
	ExpiresAt   *time.Time `json:"expires_at"`
	RevokedAt   *time.Time `json:"revoked_at"`
}

SCIMTokenInfo represents token information (without sensitive data)

type SCIMTokenListResponse

type SCIMTokenListResponse struct {
	Tokens []SCIMTokenInfo `json:"tokens"`
	Total  int             `json:"total" example:"5"`
	Limit  int             `json:"limit" example:"50"`
	Offset int             `json:"offset" example:"0"`
}

SCIMTokenListResponse represents a list of tokens response

type SCIMTokenResponse

type SCIMTokenResponse struct {
	Token   string `json:"token" example:"scim_abc123"`
	ID      string `json:"id" example:"01HZ"`
	Name    string `json:"name" example:"Production SCIM Token"`
	Message string `json:"message" example:"Store this token securely"`
}

SCIMTokenResponse represents a token creation response

type SCIMUser

type SCIMUser struct {
	// Common attributes
	Schemas    []string  `json:"schemas"`
	ID         string    `json:"id"`
	ExternalID string    `json:"externalId,omitempty"`
	Meta       *SCIMMeta `json:"meta"`

	// Core User Schema attributes
	UserName          string    `json:"userName"`
	Name              *SCIMName `json:"name,omitempty"`
	DisplayName       string    `json:"displayName,omitempty"`
	NickName          string    `json:"nickName,omitempty"`
	ProfileURL        string    `json:"profileUrl,omitempty"`
	Title             string    `json:"title,omitempty"`
	UserType          string    `json:"userType,omitempty"`
	PreferredLanguage string    `json:"preferredLanguage,omitempty"`
	Locale            string    `json:"locale,omitempty"`
	Timezone          string    `json:"timezone,omitempty"`
	Active            bool      `json:"active"`
	Password          string    `json:"password,omitempty"`

	// Multi-valued attributes
	Emails           []Email           `json:"emails,omitempty"`
	PhoneNumbers     []PhoneNumber     `json:"phoneNumbers,omitempty"`
	IMs              []IM              `json:"ims,omitempty"`
	Photos           []Photo           `json:"photos,omitempty"`
	Addresses        []SCIMAddress     `json:"addresses,omitempty"`
	Groups           []GroupReference  `json:"groups,omitempty"`
	Entitlements     []Entitlement     `json:"entitlements,omitempty"`
	Roles            []SCIMRole        `json:"roles,omitempty"`
	X509Certificates []X509Certificate `json:"x509Certificates,omitempty"`

	// Enterprise extension
	EnterpriseUser *EnterpriseUser `json:"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User,omitempty"`
}

SCIMUser represents a SCIM 2.0 User resource (RFC 7643 Section 4.1)

type Schema

type Schema struct {
	ID          string      `json:"id"`
	Name        string      `json:"name,omitempty"`
	Description string      `json:"description,omitempty"`
	Attributes  []Attribute `json:"attributes"`
	Meta        *SCIMMeta   `json:"meta,omitempty"`
}

Schema represents a SCIM schema (RFC 7643 Section 7)

type SchemaExtension

type SchemaExtension struct {
	Schema   string `json:"schema"`
	Required bool   `json:"required"`
}

SchemaExtension represents a schema extension (RFC 7643 Section 6)

type SearchConfig

type SearchConfig struct {
	MaxResults     int      `json:"max_results" yaml:"max_results"`         // Max results per page
	DefaultResults int      `json:"default_results" yaml:"default_results"` // Default page size
	AllowedFilters []string `json:"allowed_filters" yaml:"allowed_filters"` // Allowed filter attributes
	AllowedSortBy  []string `json:"allowed_sort_by" yaml:"allowed_sort_by"` // Allowed sort attributes
}

SearchConfig configures search and filtering behavior

type SearchRequest

type SearchRequest struct {
	Schemas            []string `json:"schemas"`
	Attributes         []string `json:"attributes,omitempty"`
	ExcludedAttributes []string `json:"excludedAttributes,omitempty"`
	Filter             string   `json:"filter,omitempty"`
	SortBy             string   `json:"sortBy,omitempty"`
	SortOrder          string   `json:"sortOrder,omitempty"` // ascending, descending
	StartIndex         int      `json:"startIndex,omitempty"`
	Count              int      `json:"count,omitempty"`
}

SearchRequest represents a SCIM search request (RFC 7644 Section 3.4.3)

type SecurityConfig

type SecurityConfig struct {
	RequireHTTPS         bool     `json:"require_https" yaml:"require_https"`
	IPWhitelist          []string `json:"ip_whitelist" yaml:"ip_whitelist"`
	AuditAllOperations   bool     `json:"audit_all_operations" yaml:"audit_all_operations"`
	MaskSensitiveData    bool     `json:"mask_sensitive_data" yaml:"mask_sensitive_data"`       // Mask emails, phones in logs
	RequireOrgValidation bool     `json:"require_org_validation" yaml:"require_org_validation"` // Validate org access
}

SecurityConfig configures security and compliance features

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service provides SCIM provisioning business logic

func NewService

func NewService(cfg ServiceConfig) *Service

NewService creates a new SCIM service

func (*Service) CreateGroup

func (s *Service) CreateGroup(ctx context.Context, scimGroup *SCIMGroup, orgID xid.ID) (*SCIMGroup, error)

CreateGroup creates a new group (maps to team/role)

func (*Service) CreateProvider added in v0.0.5

func (s *Service) CreateProvider(ctx context.Context, req *CreateSCIMProviderRequest) (*SCIMProvider, error)

CreateProvider creates a new SCIM provider

func (*Service) CreateProvisioningLog

func (s *Service) CreateProvisioningLog(ctx context.Context, log *ProvisioningLog) error

CreateProvisioningLog creates a new provisioning log entry

func (*Service) CreateProvisioningToken

func (s *Service) CreateProvisioningToken(ctx context.Context, appID, envID, orgID xid.ID, name, description string, scopes []string, expiresAt *time.Time) (string, *ProvisioningToken, error)

CreateProvisioningToken creates a new SCIM provisioning token Updated for 3-tier architecture: App → Environment → Organization

Example

Example: Creating a provisioning token

package main

import ()

func main() {
	// Get SCIM service
	// scimService := scimPlugin.Service()

	// Create token for Okta integration (3-tier architecture)
	// appID := xid.New()
	// envID := xid.New()
	// orgID := xid.New()
	// token, provToken, err := scimService.CreateProvisioningToken(
	// 	ctx,
	// 	appID,                                     // App ID
	// 	envID,                                     // Environment ID
	// 	orgID,                                     // Organization ID
	// 	"Okta Production",                         // Token name
	// 	"SCIM token for Okta prod environment",   // Description
	// 	[]string{"scim:read", "scim:write"},      // Scopes
	// 	&expiresAt,                                // Expiration
	// )

	// Store token securely (shown only once)
	// fmt.Printf("Token: %s\n", token)
	// fmt.Printf("Token ID: %s\n", provToken.ID)
}

func (*Service) CreateToken added in v0.0.5

func (s *Service) CreateToken(ctx context.Context, req *CreateSCIMTokenRequest) (*SCIMToken, error)

CreateToken creates a new SCIM token

func (*Service) CreateUser

func (s *Service) CreateUser(ctx context.Context, scimUser *SCIMUser, orgID xid.ID) (*SCIMUser, error)

CreateUser provisions a new user via SCIM

func (*Service) DeleteGroup

func (s *Service) DeleteGroup(ctx context.Context, id, orgID xid.ID) error

DeleteGroup deletes a group

func (*Service) DeleteUser

func (s *Service) DeleteUser(ctx context.Context, id, orgID xid.ID) error

DeleteUser de-provisions a user

func (*Service) GetAttributeMappings

func (s *Service) GetAttributeMappings(ctx context.Context, appID, envID, orgID xid.ID) (map[string]string, error)

GetAttributeMappings retrieves attribute mappings for an organization Updated for 3-tier architecture: App → Environment → Organization

func (*Service) GetConfigForOrg added in v0.0.5

func (s *Service) GetConfigForOrg(ctx context.Context, orgID xid.ID) (*Config, error)

GetConfigForOrg returns SCIM configuration for an organization

func (*Service) GetDashboardStats added in v0.0.5

func (s *Service) GetDashboardStats(ctx context.Context, appID xid.ID, orgID *xid.ID) (*DashboardStats, error)

GetDashboardStats returns statistics for dashboard widgets

func (*Service) GetDetailedStats added in v0.0.5

func (s *Service) GetDetailedStats(ctx context.Context, appID xid.ID, orgID *xid.ID) (*DetailedStats, error)

GetDetailedStats returns detailed statistics for analytics

func (*Service) GetFailedEvents added in v0.0.5

func (s *Service) GetFailedEvents(ctx context.Context, appID xid.ID, orgID *xid.ID, limit int) ([]*SCIMSyncEvent, error)

GetFailedEvents returns recent failed events

func (*Service) GetFailedOperationsCount added in v0.0.5

func (s *Service) GetFailedOperationsCount(ctx context.Context, appID xid.ID, orgID *xid.ID) (int, error)

GetFailedOperationsCount returns count of failed operations

func (*Service) GetGroup

func (s *Service) GetGroup(ctx context.Context, id, orgID xid.ID) (*SCIMGroup, error)

GetGroup retrieves a group by ID

func (*Service) GetProvider added in v0.0.5

func (s *Service) GetProvider(ctx context.Context, providerID xid.ID) (*SCIMProvider, error)

GetProvider gets a provider by ID

func (*Service) GetProviderHealth added in v0.0.5

func (s *Service) GetProviderHealth(ctx context.Context, providerID xid.ID) (*ProviderHealth, error)

GetProviderHealth checks provider health status

func (*Service) GetProviderStatsForOrg added in v0.0.5

func (s *Service) GetProviderStatsForOrg(ctx context.Context, orgID xid.ID) (*ProviderStats, error)

GetProviderStatsForOrg returns provider statistics for an organization

func (*Service) GetProviderSyncHistory added in v0.0.5

func (s *Service) GetProviderSyncHistory(ctx context.Context, providerID xid.ID, limit int) ([]*SCIMSyncEvent, error)

GetProviderSyncHistory gets sync history for a provider

func (*Service) GetProvidersForOrg added in v0.0.5

func (s *Service) GetProvidersForOrg(ctx context.Context, orgID xid.ID) ([]interface{}, error)

GetProvidersForOrg returns SCIM providers for an organization

func (*Service) GetProvisioningLogs

func (s *Service) GetProvisioningLogs(ctx context.Context, appID, envID, orgID xid.ID, action string, limit, offset int) ([]*ProvisioningLog, int, error)

GetProvisioningLogs retrieves provisioning logs with filtering Updated for 3-tier architecture

func (*Service) GetRecentActivity added in v0.0.5

func (s *Service) GetRecentActivity(ctx context.Context, appID xid.ID, orgID *xid.ID, limit int) ([]*SCIMSyncEvent, error)

GetRecentActivity returns recent provisioning events

func (*Service) GetRecentEventsForOrg added in v0.0.5

func (s *Service) GetRecentEventsForOrg(ctx context.Context, orgID xid.ID, limit int) ([]interface{}, error)

GetRecentEventsForOrg returns recent sync events for an organization

func (*Service) GetSyncLogs added in v0.0.5

func (s *Service) GetSyncLogs(ctx context.Context, appID xid.ID, orgID *xid.ID, page, perPage int, statusFilter, eventTypeFilter string) ([]*SCIMSyncEvent, int, error)

GetSyncLogs returns sync logs with pagination and filtering

func (*Service) GetSyncStatsForOrg added in v0.0.5

func (s *Service) GetSyncStatsForOrg(ctx context.Context, orgID xid.ID) (*SyncStats, error)

GetSyncStatsForOrg returns sync statistics for an organization

func (*Service) GetSyncStatus added in v0.0.5

func (s *Service) GetSyncStatus(ctx context.Context, appID xid.ID, orgID *xid.ID) (*SyncStatus, error)

GetSyncStatus returns current sync status

func (*Service) GetSyncStatusForOrg added in v0.0.5

func (s *Service) GetSyncStatusForOrg(ctx context.Context, orgID xid.ID) (*SyncStatus, error)

GetSyncStatusForOrg returns sync status for a specific organization

func (*Service) GetUser

func (s *Service) GetUser(ctx context.Context, id, orgID xid.ID) (*SCIMUser, error)

GetUser retrieves a user by ID

func (*Service) Health

func (s *Service) Health(ctx context.Context) error

Health checks service health

func (*Service) InitializeOrgSCIMConfig

func (s *Service) InitializeOrgSCIMConfig(ctx context.Context, appID, envID, orgID xid.ID) error

InitializeOrgSCIMConfig initializes default SCIM config for an organization Updated for 3-tier architecture: App → Environment → Organization

func (*Service) ListGroups

func (s *Service) ListGroups(ctx context.Context, orgID xid.ID, filter string, startIndex, count int) (*ListResponse, error)

ListGroups lists groups with filtering and pagination

func (*Service) ListProviders added in v0.0.5

func (s *Service) ListProviders(ctx context.Context, appID xid.ID, orgID *xid.ID) ([]*SCIMProvider, error)

ListProviders lists SCIM providers

func (*Service) ListProvisioningTokens

func (s *Service) ListProvisioningTokens(ctx context.Context, appID, envID, orgID xid.ID, limit, offset int) ([]*ProvisioningToken, int, error)

ListProvisioningTokens lists all provisioning tokens for an organization Updated for 3-tier architecture

func (*Service) ListTokens added in v0.0.5

func (s *Service) ListTokens(ctx context.Context, appID, envID *xid.ID, orgID *xid.ID) ([]*SCIMToken, error)

ListTokens lists SCIM tokens

func (*Service) ListUsers

func (s *Service) ListUsers(ctx context.Context, orgID xid.ID, filter string, startIndex, count int) (*ListResponse, error)

ListUsers lists users with filtering and pagination

func (*Service) Migrate

func (s *Service) Migrate(ctx context.Context) error

Migrate runs database migrations

func (*Service) ProcessBulkOperation

func (s *Service) ProcessBulkOperation(ctx context.Context, bulkReq *BulkRequest, orgID xid.ID) (*BulkResponse, error)

ProcessBulkOperation processes a bulk operation request

func (*Service) RemoveProvider added in v0.0.5

func (s *Service) RemoveProvider(ctx context.Context, providerID xid.ID) error

RemoveProvider removes a provider

func (*Service) ReplaceGroup

func (s *Service) ReplaceGroup(ctx context.Context, id, orgID xid.ID, scimGroup *SCIMGroup) (*SCIMGroup, error)

ReplaceGroup replaces a group via PUT

func (*Service) ReplaceUser

func (s *Service) ReplaceUser(ctx context.Context, id, orgID xid.ID, scimUser *SCIMUser) (*SCIMUser, error)

ReplaceUser replaces a user via SCIM PUT

func (*Service) RevokeProvisioningToken

func (s *Service) RevokeProvisioningToken(ctx context.Context, tokenID string) error

RevokeProvisioningToken revokes a provisioning token

func (*Service) RevokeToken added in v0.0.5

func (s *Service) RevokeToken(ctx context.Context, tokenID xid.ID) error

RevokeToken revokes a token

func (*Service) RotateToken added in v0.0.5

func (s *Service) RotateToken(ctx context.Context, tokenID xid.ID) (*SCIMToken, error)

RotateToken rotates an existing token

func (*Service) SendProvisioningWebhook

func (s *Service) SendProvisioningWebhook(ctx context.Context, event string, data map[string]interface{}) error

SendProvisioningWebhook sends a provisioning webhook

func (*Service) Shutdown

func (s *Service) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the service

func (*Service) TestConnection added in v0.0.5

func (s *Service) TestConnection(ctx context.Context, tokenID xid.ID) (*ConnectionTestResult, error)

TestConnection tests SCIM endpoint connectivity for a token

func (*Service) TriggerManualSync added in v0.0.5

func (s *Service) TriggerManualSync(ctx context.Context, providerID xid.ID, syncType string) error

TriggerManualSync initiates a manual sync operation

func (*Service) UpdateAttributeMappings

func (s *Service) UpdateAttributeMappings(ctx context.Context, appID, envID, orgID xid.ID, mappings map[string]string) error

UpdateAttributeMappings updates attribute mappings for an organization Updated for 3-tier architecture: App → Environment → Organization

func (*Service) UpdateGroup

func (s *Service) UpdateGroup(ctx context.Context, id, orgID xid.ID, patch *PatchOp) (*SCIMGroup, error)

UpdateGroup updates a group via PATCH

func (*Service) UpdateUser

func (s *Service) UpdateUser(ctx context.Context, id, orgID xid.ID, patch *PatchOp) (*SCIMUser, error)

UpdateUser updates a user via SCIM PATCH

func (*Service) ValidateProvisioningToken

func (s *Service) ValidateProvisioningToken(ctx context.Context, token string) (*ProvisioningToken, error)

ValidateProvisioningToken validates a bearer token

type ServiceConfig

type ServiceConfig struct {
	Config         *Config
	Repository     *Repository
	UserService    user.ServiceInterface // Use interface to support decorated services
	OrgService     interface{}           // Can be *app.ServiceImpl or *orgplugin.ServiceImpl
	AuditService   *audit.Service
	WebhookService *webhook.Service
}

ServiceConfig holds service dependencies

type ServiceProviderConfig

type ServiceProviderConfig struct {
	Schemas               []string               `json:"schemas"`
	DocumentationURI      string                 `json:"documentationUri,omitempty"`
	Patch                 *Supported             `json:"patch"`
	Bulk                  *BulkSupport           `json:"bulk"`
	Filter                *FilterSupport         `json:"filter"`
	ChangePassword        *Supported             `json:"changePassword"`
	Sort                  *Supported             `json:"sort"`
	Etag                  *Supported             `json:"etag"`
	AuthenticationSchemes []AuthenticationScheme `json:"authenticationSchemes"`
	Meta                  *SCIMMeta              `json:"meta"`
}

ServiceProviderConfig represents the service provider configuration (RFC 7643 Section 5)

type StatsResponse

type StatsResponse struct {
	TotalOperations int               `json:"totalOperations"`
	SuccessCount    int               `json:"successCount"`
	FailureCount    int               `json:"failureCount"`
	SuccessRate     float64           `json:"successRate"`
	ByOperation     map[string]int    `json:"byOperation"`
	ByResourceType  map[string]int    `json:"byResourceType"`
	ByStatus        map[string]int    `json:"byStatus"`
	Recent          []ProvisioningLog `json:"recent"`
	StartDate       *time.Time        `json:"startDate,omitempty"`
	EndDate         *time.Time        `json:"endDate,omitempty"`
}

StatsResponse represents provisioning statistics

type StatusResponse

type StatusResponse = responses.StatusResponse

type SuccessResponse

type SuccessResponse = responses.SuccessResponse

type Supported

type Supported struct {
	Supported bool `json:"supported"`
}

Supported indicates feature support (RFC 7643 Section 5)

type SyncEvent added in v0.0.5

type SyncEvent struct {
	Operation string
	Status    string
	Timestamp string
	Details   string
}

type SyncStats added in v0.0.5

type SyncStats struct {
	TotalSyncs  int
	SuccessRate float64
	FailedSyncs int
}

SyncStats holds sync statistics

type SyncStatus added in v0.0.5

type SyncStatus struct {
	IsHealthy       bool
	ActiveProviders int
	LastSync        *time.Time
	Status          string
	Message         string
}

SyncStatus holds current sync status information

type TokenListResponse

type TokenListResponse struct {
	Tokens []ProvisioningTokenInfo `json:"tokens"`
	Total  int                     `json:"total"`
}

TokenListResponse represents a list of provisioning tokens (without actual token values)

type TokenResponse

type TokenResponse struct {
	Token   string `json:"token"`
	ID      string `json:"id"`
	Name    string `json:"name"`
	Message string `json:"message"`
}

TokenResponse is the response for token creation

type UpdateAttributeMappingsRequest

type UpdateAttributeMappingsRequest struct {
	Mappings map[string]string `json:"mappings" validate:"required"`
}

UpdateAttributeMappingsRequest is the request body for updating attribute mappings

type UserProvisioningConfig

type UserProvisioningConfig struct {
	Enabled                 bool     `json:"enabled" yaml:"enabled"`
	AutoActivate            bool     `json:"auto_activate" yaml:"auto_activate"`           // Activate users immediately
	SendWelcomeEmail        bool     `json:"send_welcome_email" yaml:"send_welcome_email"` // Send welcome email on creation
	DefaultRole             string   `json:"default_role" yaml:"default_role"`             // Default role for provisioned users
	RequiredAttributes      []string `json:"required_attributes" yaml:"required_attributes"`
	PreventDuplicates       bool     `json:"prevent_duplicates" yaml:"prevent_duplicates"`                 // Prevent duplicate emails
	SoftDeleteOnDeProvision bool     `json:"soft_delete_on_deprovision" yaml:"soft_delete_on_deprovision"` // Soft delete vs hard delete
}

UserProvisioningConfig configures user provisioning behavior

type UsersResponse

type UsersResponse struct {
	Users []SCIMUser `json:"users"`
	Total int        `json:"total"`
}

UsersResponse wraps user list response for clarity

type WebhookConfig

type WebhookConfig struct {
	Enabled           bool     `json:"enabled" yaml:"enabled"`
	NotifyOnCreate    bool     `json:"notify_on_create" yaml:"notify_on_create"`
	NotifyOnUpdate    bool     `json:"notify_on_update" yaml:"notify_on_update"`
	NotifyOnDelete    bool     `json:"notify_on_delete" yaml:"notify_on_delete"`
	NotifyOnGroupSync bool     `json:"notify_on_group_sync" yaml:"notify_on_group_sync"`
	WebhookURLs       []string `json:"webhook_urls" yaml:"webhook_urls"`
	RetryAttempts     int      `json:"retry_attempts" yaml:"retry_attempts"`
	TimeoutSeconds    int      `json:"timeout_seconds" yaml:"timeout_seconds"`
}

WebhookConfig configures provisioning event webhooks

type X509Certificate

type X509Certificate struct {
	Value   string `json:"value"`
	Display string `json:"display,omitempty"`
	Type    string `json:"type,omitempty"`
	Primary bool   `json:"primary,omitempty"`
}

X509Certificate represents an X.509 certificate (RFC 7643 Section 4.1.2)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL