WF-110: Contractor Access Expiration
Overview
This workflow manages time-limited access for contractors, consultants, and temporary team members. It handles automatic deactivation at the expires_at date, sends advance notifications, processes extension requests, and ensures proper data handoff before access removal.
Trigger: Scheduled job (daily) + HTTP endpoints for extensions
Duration: Automatic (daily check) + ~2-3 seconds (extension requests)
Related Workflows: WF-005 (Invitation), WF-008 (Offboarding), WF-109 (Seat Reallocation)
Prerequisites
For contractor access management:
Contractor Membership Fields
| Field | Type | Description |
|---|
expires_at | DateTime | Access expiration timestamp |
contractor_type | Enum | contractor, consultant, temp, auditor |
sponsor_id | UUID | Admin who invited the contractor |
project_ids | Array | Projects contractor can access |
extension_count | Integer | Number of times extended |
max_extensions | Integer | Maximum allowed extensions |
Workflow Diagram
Step-by-Step Narrative
Part A: Scheduled Expiration Check
Step A1: Daily Scan
- Node: Expiration Scanner
- Type: Celery Beat Task
- Schedule: Daily at 00:00 UTC
- Actions:
- Queries all contractor memberships with upcoming expirations
- Groups by notification tier:
- 7 days out: First warning
- 3 days out: Reminder
- 1 day out: Final warning
- 0 days (today): Expiration
Step A2: 7-Day Warning
- Node: First Warning
- Type: Notification
- Actions:
- Sends email to contractor:
- Subject: "Your CODITECT access expires in 7 days"
- Content: Expiration date, extension request link
- Sends email to sponsor admin:
- Subject: "Contractor access expiring soon"
- Content: Contractor name, expiration date, extend/offboard options
- Creates in-app notification for both parties
Step A3: 1-Day Final Warning
- Node: Final Warning
- Type: Notification
- Actions:
- Sends urgent email to contractor:
- Subject: "URGENT: Your CODITECT access expires tomorrow"
- Content: Save work reminder, data export instructions
- Shows persistent banner in contractor's dashboard
- Sends final reminder to sponsor admin
Step A4: Expiration Execution
- Node: Access Termination
- Type: Multi-Action
- Actions:
- Terminate Sessions:
- End all active sessions for contractor
- Display "Access Expired" message
- Allow 5-minute grace for saving
- Revoke Permissions:
- Remove from all project access lists
- Revoke repository permissions
- Disable API keys
- Update Membership:
- Set
status to expired
- Set
expired_at to current timestamp
- Preserve record for audit (soft delete)
- License Handling:
- Release assigned license to seat pool
- Trigger WF-109 if auto-reallocation H.P.009-CONFIGured
Part B: Extension Request Flow
Step B1: Extension Request
- Node: Request Endpoint
- Type: HTTP POST
- Path:
/api/v1/memberships/{id}/request-extension
- Actions:
- Validates contractor can request extension:
- Must be within extension window (expires in ≤30 days)
- Must not exceed
max_extensions
- Creates
extension_request record:
requested_by: contractor user_id
requested_days: 30 (default) or specified
reason: provided justification
status: pending
- Node: Approval Workflow
- Type: Notification + Endpoint
- Actions:
- Sends approval request to sponsor admin:
- Email with one-click approve/deny links
- In-app approval queue notification
- Sponsor can:
- Approve: Extends
expires_at by requested days
- Deny: Sends denial notification to contractor
- Modify: Approve with different duration
Step B3: Apply Extension
- Node: Extend Access
- Type: Database Update
- Actions:
- Updates
expires_at to new date
- Increments
extension_count
- Logs extension in audit trail
- Sends confirmation to contractor and sponsor
- Clears any expiration warnings
Part C: Data Handoff
Step C1: Pre-Expiration Data Export
- Node: Data Export Reminder
- Type: Automated Email
- Timing: 7 days before expiration
- Actions:
- Reminds contractor to export personal work
- Provides data export instructions
- Lists items that will be retained by organization
Step C2: Organization Data Retention
- Node: Data Preservation
- Type: Background Job
- Actions:
- Contractor-created content remains with organization
- Personal settings and preferences removed
- Audit trail preserved for compliance
- Project history attributed to contractor (name preserved)
Error Handling
| Error | Code | Resolution |
|---|
| Extension Limit Reached | 403 | Max extensions exceeded, contact admin |
| Not Contractor | 400 | Only contractor memberships have expiration |
| Already Expired | 410 | Cannot extend already expired access |
| Sponsor Not Found | 404 | Original sponsor no longer active |
| Pending Request Exists | 409 | Wait for existing request resolution |
API Endpoints
| Method | Endpoint | Description |
|---|
| GET | /api/v1/organizations/{id}/contractors | List all contractors |
| GET | /api/v1/organizations/{id}/contractors/expiring | List expiring soon |
| POST | /api/v1/memberships/{id}/request-extension | Request extension |
| POST | /api/v1/extension-requests/{id}/approve | Approve extension |
| POST | /api/v1/extension-requests/{id}/deny | Deny extension |
| PATCH | /api/v1/memberships/{id}/expires-at | Admin set expiration |
Configuration Options
| Setting | Default | Description |
|---|
contractor_warning_days | [7, 3, 1] | Days before expiration to warn |
default_extension_days | 30 | Default extension duration |
max_extensions | 3 | Maximum extension count |
auto_reallocate_seat | true | Release license on expiration |
grace_period_minutes | 5 | Time to save work after expiration |