Skip to main content

WF-008: User Offboarding Workflow

Overview

This workflow automates the offboarding of users and organizations whose subscriptions have expired. It runs on a schedule, identifies accounts past their grace period, and performs systematic resource cleanup including workstation deletion, storage removal, and data anonymization.

Trigger: Scheduled (hourly) Duration: ~30-120 seconds per organization Related Workflows: WF-003 (Stripe Webhook triggers grace period)


Prerequisites

Before starting, ensure you have:

  • Required tools installed
  • Access to necessary resources
  • Basic understanding of concepts

Verify setup:

# Verification command

Workflow Diagram

User Offboarding Sequence


Step-by-Step Narrative

Step 1: Hourly Schedule Trigger

  • Node: Hourly Check
  • Type: Schedule Trigger
  • Interval: Every 1 hour
  • Actions:
    • Fires automatically every hour
    • Initiates check for expired subscriptions
    • Runs 24/7 for continuous compliance

Step 2: Find Expired Subscriptions

  • Node: Find Expired Subscriptions
  • Type: PostgreSQL Select
  • Table: public.organizations
  • Query Condition:
    • subscription_status = 'suspended'
    • updated_at < NOW() - INTERVAL '30 days'
  • Actions:
    • Identifies organizations 30+ days past due
    • Returns list of org IDs for processing
    • Skips organizations already offboarded

Step 3: Loop Through Organizations

  • Node: Loop Organizations
  • Type: Split In Batches
  • Batch Size: 1
  • Actions:
    • Processes one organization at a time
    • Ensures reliable cleanup with error isolation
    • Continues even if one org fails

For Each Organization:

Step 4: Get Organization Workstations

  • Node: Get Org Workstations
  • Type: PostgreSQL Select
  • Table: public.workstations
  • Actions:
    • Retrieves all workstations for the organization
    • Gets GCP workstation IDs for deletion
    • Identifies storage buckets to clean

Step 5-6: Delete Cloud Resources (Parallel)

Node 5: Delete GCP Workstation

  • Type: HTTP Request (GCP Workstations API)
  • Method: DELETE
  • Actions:
    • Calls GCP API to delete workstation
    • Stops any running VM
    • Frees allocated resources

Node 6: Delete User Storage

  • Type: Google Cloud Storage
  • Operation: Delete with prefix
  • Actions:
    • Deletes all files under org-{id}/
    • Removes project files, H.P.009-CONFIGs, cache
    • Bucket remains for other orgs

Step 7: Mark Workstations Deleted

  • Node: Mark Workstations Deleted
  • Type: PostgreSQL Update
  • Table: public.workstations
  • Actions:
    • Updates status to deleted
    • Records deleted_at timestamp
    • Maintains audit trail

Step 8: Anonymize Organization Users

  • Node: Anonymize Org Users
  • Type: PostgreSQL Update
  • Table: public.users
  • Condition: Users who are members of the organization
  • Actions:
    • Replaces email with offboarded-{id}@coditect.local
    • Sets display name to "Offboarded User"
    • Sets is_active: false
    • Preserves user ID for audit integrity

Step 9: Mark Organization Offboarded

  • Node: Mark Org Offboarded
  • Type: PostgreSQL Update
  • Table: public.organizations
  • Actions:
    • Sets subscription_status: 'offboarded'
    • Replaces name with "Offboarded Organization"
    • Records deleted_at timestamp
    • Prevents any future access

Step 10: Log Offboarding Event

  • Node: Log Offboarding Event
  • Type: PostgreSQL Insert
  • Table: public.audit_log
  • Actions:
    • Creates immutable compliance record
    • Records actor as system
    • Documents reason: subscription_expired
    • Notes 30-day grace period was honored

Step 11: Publish Offboard Event

  • Node: Publish Offboard Event
  • Type: Google Cloud Pub/Sub
  • Topic: billing-events
  • Actions:
    • Publishes organization.offboarded event
    • Includes org ID and timestamp
    • Enables downstream cleanup
    • Triggers analytics update

Step 12: Continue Loop

  • Node: Loop back to Step 3
  • Actions:
    • Returns to batch splitter
    • Processes next organization
    • Continues until all processed

Data Flow

Schedule Trigger → Find Expired Orgs

For each organization:

Input (from query):
{
"id": "org-uuid",
"name": "Expired Corp",
"subscription_status": "suspended",
"updated_at": "2023-12-15T10:00:00Z"
}

After processing:
{
"id": "org-uuid",
"name": "Offboarded Organization",
"subscription_status": "offboarded",
"deleted_at": "2024-01-15T10:30:00Z"
}

Users updated:
- email: offboarded-{id}@coditect.local
- display_name: Offboarded User
- is_active: false

Pub/Sub Event:
{
"event": "organization.offboarded",
"org_id": "org-uuid",
"timestamp": "2024-01-15T10:30:00Z"
}

Offboarding Timeline

DayStatusAction
0Payment failsWF-003 starts grace period
1-7past_dueDaily email reminders
8-14past_dueWorkstation suspended (not deleted)
15-30suspendedFinal warning emails
30+suspendedThis workflow runs, full offboarding

Resources Deleted

ResourceActionRecoverable?
GCP WorkstationDeleted via APINo
Cloud Storage filesDeleted with prefixNo
User PIIAnonymizedNo (GDPR compliance)
SubscriptionStatus → offboardedRe-subscribe only

Resources Retained

ResourceReasonRetention Period
Billing recordsTax compliance7 years
Audit logsSecurity compliance1 year
Invoice historyLegal requirements7 years
Anonymized user IDAudit trail integrityIndefinite

Monitoring and Alerts

Prometheus Metrics:

  • offboarding_orgs_processed_total
  • offboarding_duration_seconds
  • offboarding_errors_total

Alerting:

  • Failed offboarding → Alert ops team
  • High error rate → Page on-call
  • Unexpected delay → Warning notification

Error Handling

ErrorCauseAction
GCP API 404Workstation already deletedLog and continue
GCP API 403Permission issueAlert ops, skip org
DB connection failureNetwork issueRetry with backoff
Storage delete timeoutLarge data volumeAsync cleanup queue

Error Isolation: Each organization processed independently. One failure doesn't stop processing of others.


Security Considerations

  • Runs as system service account (not user context)
  • Service account has minimal required permissions
  • All actions logged to immutable audit trail
  • No user data exposed in logs
  • PII anonymized, not deleted (maintains audit integrity)
  • 30-day grace period legally documented

Compliance Notes

This workflow ensures compliance with:

  • GDPR Article 17: Right to erasure (anonymization fulfills this)
  • GDPR Article 5(1)(e): Storage limitation (data not kept beyond necessity)
  • SOC 2: Proper offboarding controls
  • Data retention policy: Grace period documentation

Troubleshooting

Common Issue 1

Problem: Description of issue Solution: Steps to resolve

Common Issue 2

Problem: Description of issue Solution: Steps to resolve

Next Steps

After completing this guide:

  1. Explore: Additional related features
  2. Practice: Apply concepts in your project
  3. Reference: Related documentation