Post

Worst Part Of The Job Today

Worst Part Of The Job Today

Worst Part Of The Job Today

Introduction

The terminal blinked back at me with cold indifference as I typed the commands - userdel jsmith, passwd -l jsmith, az ad user delete --id jsmith@contoso.com. Each keystroke felt like driving nails into a coffin. My colleague’s Slack avatar grayed out instantly, their GitHub contributions graph froze mid-curve, and their SSH keys evaporated from production systems. This is the worst part of our profession - the digital euthanasia required when team members leave organizations, whether through tragedy, termination, or transition.

In the world of DevOps and system administration, we architect robust infrastructures, automate deployment pipelines, and harden security postures. But no certification prepares you for the moment when infrastructure management intersects with human mortality. The Reddit sysadmin who shared their experience of disabling a deceased coworker’s account articulated what many of us have felt but seldom discuss - the emotional weight of our technical responsibilities.

This guide addresses the unspoken reality of privileged access management in extreme scenarios. We’ll examine:

  1. The technical and ethical dimensions of account deprovisioning
  2. Automated systems for access revocation
  3. Audit trails and compliance requirements
  4. Psychological considerations for technical teams

Whether managing enterprise Active Directory forests or self-hosted homelab environments, these principles remain critical. A single stale credential can become an attack vector, yet reckless deletion can destroy institutional knowledge. We’ll navigate this minefield with technical precision and human sensitivity.

Understanding Account Deprovisioning

What Is Access Revocation?

Account deprovisioning is the systematic removal of digital privileges and credentials from users who no longer require access. In DevOps contexts, this spans multiple layers:

Access LayerExamplesRisks of Inadequate Deprovisioning
InfrastructureSSH keys, VPN credentialsPrivilege escalation, data exfiltration
Cloud PlatformsIAM roles, service principalsResource hijacking, cryptojacking
Development ToolsGit repositories, CI/CD pipelinesCode sabotage, secret leakage
Business SystemsCRM, ERP, HRIS accessData privacy violations, fraud

The Evolution of Identity Management

The history of access control reveals why deprovisioning remains challenging:

  1. Mainframe Era (1960s): Physical access logs and shared operator accounts
  2. Client-Server (1980s): Domain controllers with manual user management
  3. Directory Services (1990s): LDAP/Active Directory with group policies
  4. Cloud Era (2010s): Federated identities across SaaS/PaaS/IaaS
  5. Zero Trust (2020s): Continuous authentication with JIT access

Each paradigm added complexity. Modern organizations average 75 SaaS applications per employee (BetterCloud, 2022), creating a sprawling attack surface that demands automated deprovisioning.

Technical and Ethical Challenges

Technical Complexities:

  • Orphaned resources (S3 buckets, VM instances)
  • Service account dependencies
  • Multi-cloud IAM inconsistencies
  • Replication latency in distributed systems

Human Factors:

  • Emotional impact on technical staff
  • Legal requirements (SOX, HIPAA, GDPR)
  • Knowledge preservation vs. security
  • Cultural norms around digital legacy

Prerequisites for Responsible Deprovisioning

Technical Foundation

Before implementing deprovisioning workflows, ensure:

  1. Centralized Identity Provider:
    • Active Directory (on-prem)
    • Azure AD/Entra ID (cloud)
    • OpenLDAP (open-source)
    • Okta/Ping Identity (SaaS)
  2. Automation Capabilities:
    • SCIM 2.0 provisioning
    • Webhook integrations
    • Infrastructure-as-Code (Terraform, CloudFormation)
  3. Audit Systems:
    • SIEM (Splunk, ELK Stack)
    • CloudTrail/Azure Activity Logs
    • Open-source alternatives like Wazuh

Policy Requirements

  1. Legal Compliance:
    • GDPR Article 17 (Right to Erasure)
    • CCPA Section 1798.105
    • HIPAA Security Rule §164.308(a)(3)(ii)(C)
  2. HR Integration:
    • Termination workflow triggers
    • Manager approval chains
    • Legal hold exceptions
  3. Technical Safeguards:
    • 48-hour delay for permanent deletion
    • Backup restoration process
    • Break-glass accounts

Pre-Implementation Checklist

  1. Document all identity stores and dependencies
  2. Establish HRIS integration points
  3. Create encrypted backup process
  4. Define roles with privileged access management
  5. Implement mandatory access logging

Automated Deprovisioning Implementation

Active Directory Example

For on-premise environments, automate user disablement via PowerShell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Disable AD account with termination reason
Disable-ADAccount -Identity $Username -Confirm:$false

# Remove group memberships except baseline
Get-ADUser $Username -Properties MemberOf | 
    ForEach-Object {$_.MemberOf} | 
    Remove-ADGroupMember -Members $Username -Confirm:$false

# Move to Disabled Users OU
Get-ADUser $Username | Move-ADObject -TargetPath "OU=Disabled,DC=contoso,DC=com"

# Export attributes for legal preservation
Get-ADUser $Username -Properties * | 
    Export-Clixml -Path "\\archive\users\$Username.xml"

Cloud Identity (Azure AD) Automation

Azure Automation Runbook for cloud identities:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Connect-AzureAD

# Revoke active sessions
Revoke-AzureADUserAllRefreshToken -ObjectId $User.ObjectId

# Disable account
Set-AzureADUser -ObjectId $User.ObjectId -AccountEnabled $false

# Remove licenses to prevent billing
$Licenses = Get-AzureADUserLicenseDetail -ObjectId $User.ObjectId
Set-AzureADUserLicense -ObjectId $User.ObjectId -RemoveLicenses $Licenses.SkuId

# Remove group memberships
Get-AzureADUserMembership -ObjectId $User.ObjectId | 
    ForEach-Object {
        Remove-AzureADGroupMember -ObjectId $_.ObjectId -MemberId $User.ObjectId
    }

Infrastructure-as-Code (Terraform)

Manage cloud resources through version-controlled definitions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# terraform/modules/iam/main.tf

data "aws_iam_user" "employee" {
  for_each = toset(var.active_users)
  user_name = each.key
}

resource "aws_iam_user_policy_attachment" "revoke" {
  for_each = { for u in var.terminated_users : u => u if contains(var.active_users, u) == false }
  
  user       = each.value
  policy_arn = aws_iam_policy.deny_all.arn
}

resource "aws_iam_policy" "deny_all" {
  name        = "deny-all-access"
  description = "Policy to deny all actions"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action   = ["*"]
        Effect   = "Deny"
        Resource = "*"
      }
    ]
  })
}

Verification Workflow

After deprovisioning, validate effectiveness:

1
2
3
4
5
6
7
8
9
10
11
# Check AWS IAM access
aws iam simulate-principal-policy \
    --policy-source-arn arn:aws:iam::123456789012:user/jsmith \
    --action-names "s3:*" "ec2:*"

# Test Azure AD sign-in (requires admin consent)
Invoke-MgBetaSignIn -UserId $User.Id -IsInteractive:$false

# Verify Linux account status
getent passwd $USERNAME
sudo -U $USERNAME -l

Configuration Best Practices

Security Hardening

  1. Temporal Access: ```yaml

    Okta policy example

    policies:

    • type: OAUTH_AUTHORIZATION_POLICY conditions: people: users: exclude: [DEACTIVATED] grant: lifetime: value: 1 unit: HOURS ```
  2. JIT Privileges:
    1
    2
    3
    4
    5
    6
    7
    8
    
    # Boundary configuration
    resource "boundary_role" "db_admin" {
      scope_id       = boundary_scope.project.id
      grant_scope_id = boundary_scope.project.id
      grant_strings  = ["id=*;type=*;actions=*"]
      principal_ids  = [boundary_user.jsmith.id]
      duration       = "3600" # 1 hour
    }
    

Performance Optimization

Batch processing for large-scale operations:

1
2
3
4
5
6
7
8
9
10
11
12
13
# Python pseudocode for batch deprovisioning
def disable_users(users):
    with ThreadPoolExecutor(max_workers=8) as executor:
        futures = []
        for user in users:
            futures.append(executor.submit(
                disable_single_user, 
                user,
                preserve_home=True
            ))
        
        for future in as_completed(futures):
            log_operation(future.result())

Dependency Mapping

Visualize account relationships before deletion:

graph LR
    A[User Account] --> B[SSH Keys]
    A --> C[OAuth Tokens]
    A --> D[CI/CD Pipelines]
    A --> E[Cloud Resources]
    E --> F[S3 Buckets]
    E --> G[EC2 Instances]
    E --> H[Lambda Functions]

Operational Considerations

Monitoring and Alerting

Detect stale credentials with Splunk SPL:

index=aws (eventName=ListBuckets OR eventName=DescribeInstances) 
| eval user_type=case(
    match(userIdentity.arn,".*:assumed-role.*"), "Role",
    match(userIdentity.arn,".*:user.*"), "User",
    1=1, "Other")
| stats count by userIdentity.arn, user_type
| where user_type="User" 
| lookup terminated_users.csv userIdentity.arn OUTPUTNEW termination_date
| where termination_date < relative_time(now(), "-24h")

Backup Strategy

Preserve critical data without retaining credentials:

1
2
3
4
5
# Archive home directory without SSH keys
tar --exclude='.ssh' --exclude='.aws' -czvf /backups/$USERNAME.tar.gz /home/$USERNAME

# Encrypt backup with age
age -R ~/.ssh/backup_key.pub /backups/$USERNAME.tar.gz > $USERNAME.tar.gz.age

Knowledge Transfer Protocol

Before deprovisioning technical staff:

  1. Rotate shared secrets (API keys, database passwords)
  2. Transfer repository ownership
  3. Document tribal knowledge
  4. Archive credential-free configurations

Knowledge capture template

Critical Systems Owned

  • Load Balancer Configs (HAProxy)
  • Certificate Renewal Process
  • Database Backup Scripts

Pending Tasks

  1. Certificate renewal due 2024-03-15
  2. Storage volume expansion ticket #4512

Unique Configurations

  • Custom kernel parameters in /etc/sysctl.d/99-tuning.conf
  • AWS S3 lifecycle policy exceptions ```

Troubleshooting Deprovisioning Issues

Common Problems and Solutions

SymptomDiagnosisResolution
Access persists after revocationReplication delayCheck directory sync status; force replication
Service disruptionsOrphaned service dependenciesAudit systemd units/cron jobs before removal
Compliance failuresIncomplete loggingEnable auditd rules for user modifications
License overagesFailed license deallocationVerify API responses from SaaS providers

Debugging Commands

Active Directory replication status:

1
repadmin /showrepl dc=contoso,dc=com

AWS effective permissions check:

1
2
3
aws iam simulate-custom-policy \
    --policy-input-list file://policy.json \
    --action-names s3:ListBuckets ec2:StartInstances

Linux account verification:

1
2
3
4
5
6
7
8
# Check locked status
passwd -S $USERNAME

# Verify PAM restrictions
grep $USERNAME /etc/security/access.conf

# Audit recent activity
ausearch -ua $USERNAME -ts today

Conclusion

Account deprovisioning represents the intersection of technical rigor and human empathy in system administration. Through automated workflows, comprehensive auditing, and thoughtful process design, we can fulfill our security obligations while respecting the human dimension of these operations.

Key takeaways:

  1. Automate Compassion: Build systems that handle revocation consistently, removing ad-hoc emotional burden
  2. Audit Relentlessly: Implement immutable logs of all access changes
  3. Preserve Context: Archive non-sensitive user data before deletion
  4. Psychological Safety: Create team protocols for handling difficult deprovisioning scenarios

As infrastructure grows increasingly ephemeral, our approach to digital identity must balance security with humanity. The commands we execute in these moments - whether userdel, Remove-AdUser, or gcloud iam service-accounts delete - carry weight beyond their technical function. They represent the final interface between a colleague’s digital presence and organizational memory.

For further learning:

In the end, we manage machines to serve people - even when our duties require us to erase their digital footprints. That balance defines professional infrastructure management at its most challenging and most necessary.

This post is licensed under CC BY 4.0 by the author.