User Provisioning Guide¶
This guide explains how users are automatically provisioned when they connect to your partner application through OAuth, and how this enables seamless SSO authentication.
Overview¶
When users connect your partner application to Contio via OAuth, the platform handles account creation automatically. This auto-provisioning feature eliminates the need for manual user setup, creating a frictionless onboarding experience for your users.
The User Journey¶
sequenceDiagram
participant User
participant YourApp as "Your Application"
participant Contio as "Contio"
User->>YourApp: Click "Connect to Contio"
YourApp->>Contio: Redirect to OAuth
Note over Contio: User enters email + OTP
Note over Contio: Display consent screen
User->>Contio: Grant permission
Note over Contio: Account created (if new user)
Note over Contio: Partner connection established
Contio->>YourApp: Redirect with authorization code
YourApp->>Contio: Exchange code for tokens
Note over YourApp: User is connected! How Auto-Provisioning Works¶
When a user completes the OAuth flow with your partner application, Contio automatically:
- Creates a new account if the user doesn't already have one
- Creates a personal workspace for the user (or adds them to a shared workspace—see below)
- Establishes the partner connection linking the user to your application
- Returns access tokens for your application to use
This all happens seamlessly during the standard OAuth authorization flow—no additional API calls or setup required.
What Gets Created¶
| Resource | Description |
|---|---|
| User Account | Created with the email address from the OAuth flow |
| Workspace | A personal workspace, or the shared workspace specified via workspace_id |
| Partner Connection | Links the user to your partner application, enabling data access |
Existing Users¶
If the user already has a Contio account:
- No duplicate account is created
- The partner connection is added to their existing account
- Access tokens are issued for your application
- Consent is recorded for your requested scopes
Shared Workspace Provisioning¶
By default, each new user gets their own personal workspace. If your application needs multiple users to collaborate in the same workspace, you can provision users into a shared workspace by passing workspace_id (and optionally is_admin) in the authentication initiation request.
How It Works¶
When calling POST /auth/initiate, include the optional workspace_id field to place the user into an existing workspace instead of creating a new one:
{
"email": "user@example.com",
"client_id": "partner_abc123",
"name": "Jane Smith",
"workspace_id": "550e8400-e29b-41d4-a716-446655440000",
"is_admin": false
}
| Field | Type | Required | Description |
|---|---|---|---|
workspace_id | string (UUID) | No | ID of an existing workspace to add the user to. Must belong to a user provisioned by your partner app. If omitted, a personal workspace is created. |
is_admin | boolean | No | If true, the user is granted WORKSPACE_ADMIN role in the shared workspace. Defaults to false (WORKSPACE_MEMBER). |
Validation Rules¶
The following validations are performed when workspace_id is provided:
| Condition | HTTP Status | Error Code | Description |
|---|---|---|---|
workspace_id is not a valid UUID | 400 | invalid_request | The value must be a valid UUID format |
| Workspace does not exist | 404 | workspace_not_found | No workspace found with the given ID |
| Workspace not owned by partner | 403 | workspace_not_authorized | The workspace must belong to a user provisioned by your partner app |
| User already in a different workspace | 409 | workspace_conflict | The user already belongs to another workspace |
Typical Flow¶
sequenceDiagram
participant Partner as Your Application
participant Contio as Contio API
Note over Partner: First user (workspace creator)
Partner->>Contio: POST /auth/initiate (no workspace_id)
Note over Contio: Creates user + personal workspace
Contio->>Partner: 200 OK
Note over Partner: Retrieve workspace_id from user profile
Partner->>Contio: GET /v1/partner/user/profile
Contio->>Partner: { workspace_id: "ws-123", ... }
Note over Partner: Subsequent users (shared workspace)
Partner->>Contio: POST /auth/initiate { workspace_id: "ws-123" }
Note over Contio: Creates user in existing workspace
Contio->>Partner: 200 OK User Profile Response¶
After provisioning, the user profile endpoint returns workspace details:
{
"id": "user-uuid",
"display_name": "Jane Smith",
"email": "jane@example.com",
"workspace_id": "550e8400-e29b-41d4-a716-446655440000",
"workspace_name": "Acme Corp",
"workspace_role": "WORKSPACE_MEMBER",
"created_at": "2026-01-15T10:30:00Z"
}
The workspace_role field indicates the user's role: WORKSPACE_OWNER, WORKSPACE_ADMIN, or WORKSPACE_MEMBER.
The Connection Matters¶
The partner connection created during OAuth is essential—it represents the user's explicit consent for your application to access their Contio data. This connection:
- Authorizes your application to access the user's meetings, action items, and other data within your requested scopes
- Enables SSO authentication so users can later sign in via your identity provider (if configured)
- Persists until revoked by the user or your application
OAuth Before SSO
Users must complete the OAuth flow at least once before they can use SSO. The OAuth flow establishes the partner connection and consent; SSO then uses this existing connection for authentication convenience. SSO alone cannot create new accounts or connections.
Enabling SSO After OAuth¶
Once users have connected via OAuth, you can offer them a more convenient login experience through Partner IdP SSO. Here's how the two work together:
First-Time User Flow (OAuth Connection)¶
sequenceDiagram
participant User
participant YourApp as "Your Application"
participant Contio as "Contio"
User->>YourApp: Click "Connect to Contio"
YourApp->>Contio: Redirect to OAuth
Note over Contio: User enters email + OTP
Note over Contio: Display consent screen
User->>Contio: Grant permission
Note over Contio: Account created (if new)
Note over Contio: Partner connection established
Contio->>YourApp: Authorization code
YourApp->>Contio: Exchange for tokens
Note over YourApp: User is connected! Returning User Flow (SSO Sign-In)¶
sequenceDiagram
participant User
participant YourApp as "Your Application"
participant YourIdP as "Your IdP"
participant Contio as "Contio"
User->>YourApp: Click "Sign in with SSO"
YourApp->>Contio: Redirect to /p/{slug}
Contio->>YourIdP: Redirect to IdP login
alt User has active IdP session
Note over YourIdP: Session valid - no prompt
else No active session
User->>YourIdP: Enter credentials
end
YourIdP->>Contio: Return ID token
Note over Contio: Validate token
Note over Contio: Find partner connection ✓
Contio->>YourApp: User signed in
Note over YourApp: Session established! IdP Session Behavior
Your identity provider controls the authentication experience. If the user has an active session with your IdP (e.g., they're already signed into your corporate network), they may be authenticated seamlessly without entering credentials. If no session exists—for example, when accessing via a bookmark, shared link, or after session expiration—your IdP will challenge the user for credentials as configured by your security policies.
Why This Matters¶
This two-step approach ensures:
- Explicit consent: Users knowingly authorize your application via the OAuth consent screen
- Data protection: Your application cannot access user data without prior authorization
- User control: Users can revoke access at any time
- Enterprise security: Your IdP handles authentication; Contio handles authorization
Implementation Checklist¶
To implement user provisioning in your application:
Step 1: Implement OAuth Flow¶
Follow the OAuth Flow Guide to implement the authorization code flow. When users complete this flow, they are automatically provisioned.
// Redirect users to connect
const authUrl = oauth.getAuthorizationUrl(state, [
'openid',
'profile',
'meetings:read',
'action-items:read'
]);
res.redirect(authUrl);
Step 2: Store the Connection¶
After the OAuth callback, store the user's tokens and connection status:
app.get('/callback', async (req, res) => {
const tokens = await oauth.exchangeCodeForToken(code);
// Store tokens - user is now provisioned and connected
await saveUserConnection(userId, {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresAt: Date.now() + (tokens.expires_in * 1000)
});
res.redirect('/dashboard');
});
Step 3: (Optional) Configure SSO¶
If you want to offer SSO as a login option, configure your identity provider following the SSO Integration Guide. Remember: users must complete OAuth first before SSO will work.
Handling Edge Cases¶
User Denies Consent¶
If a user denies the OAuth consent screen, no account or connection is created. Your application receives an error callback:
if (req.query.error === 'access_denied') {
// User declined - show appropriate message
res.render('connect-declined');
}
User Already Connected¶
If a user who is already connected initiates OAuth again:
- Consent may be skipped if they previously approved the same scopes
- New tokens are issued (old tokens remain valid until expiry)
- No duplicate connection is created
Reconnecting After Revocation¶
If a user or your application revokes the connection, the user can reconnect by completing the OAuth flow again. A new connection is established with fresh consent.
Security Considerations¶
Consent is Required¶
Auto-provisioning happens during OAuth specifically because the consent screen is shown. This ensures:
- Users understand what data your application will access
- Users make an informed decision to connect
- The connection is auditable and revocable
SSO Cannot Bypass Consent¶
Partner IdP SSO is designed for authentication convenience, not authorization. Even if you configure SSO:
- Users without a prior OAuth connection cannot sign in via SSO
- SSO cannot create new accounts or connections
- SSO cannot expand the scopes of an existing connection
This separation protects users from unintended data access.
Next Steps¶
- OAuth Flow Guide - Implement the OAuth authorization flow
- SSO Integration Guide - Configure your identity provider for SSO
- Webhook Events - Receive real-time updates about user activity