Automating Linux User Lifecycle with GitHub Actions: A Practical DevOps Guide

https://abhaypatil001.github.io/abhay-portfolio/
Introduction
User access management is one of the most fundamental responsibilities in any infrastructure environment, yet it is often handled in an ad hoc and manual way. In many organizations, especially during rapid development cycles, access is granted quickly but rarely reviewed or revoked with the same rigor.
Developers, vendors, and support engineers frequently require temporary access to systems. While the intention is short-term access, the implementation often becomes long-term exposure.
This article walks through a practical approach to solving this problem using GitHub Actions, starting from basic concepts and moving toward a production-ready automation pattern.
Problem Statement
In a typical environment, user access is managed manually through system administrators. A request comes in, a user is created, and access is granted. However, several issues arise with this approach:
There is no standard mechanism to enforce access duration
Users are often not removed after their task is completed
There is limited or no audit trail of who created the user and why
Access reviews are either infrequent or non-existent
Security policies like least privilege are not consistently followed
Consider a simple command:
sudo useradd ammar
This creates a user with no expiry. Unless someone explicitly removes this user later, the account remains active indefinitely.
Over time, this leads to:
Accumulation of unused accounts
Increased attack surface
Compliance and audit failures
Difficulty in tracking ownership of accounts
This is not a tooling problem; it is a process and automation problem.
Objective
The goal is to build a system that:
Creates users in a controlled and repeatable manner
Enforces an expiry date at the time of creation
Provides traceability through pipeline logs
Reduces manual intervention
Aligns with security best practices
Core Concept: User Expiry in Linux
Linux provides a built-in way to set an account expiry date at the time of user creation.
sudo useradd -e 2026-12-07 ammar
This ensures that the account becomes inactive automatically after the specified date.
To verify:
sudo chage -l ammar
This command shows account expiry and password aging details.
This is a simple but powerful feature that is often underutilized.
Solution Overview
Instead of creating users manually, we automate the process using a CI/CD pipeline.
The high-level flow looks like this:
A request is made to create a user (username + expiry date)
A GitHub Actions workflow is triggered
The workflow connects to the target server via SSH
A script runs to create the user with the specified expiry
Logs are stored in the pipeline for auditing
This approach ensures consistency, repeatability, and visibility.
Implementation
Step 1: Repository Structure
Create a repository with the following structure:
user-access-automation/
├── .github/workflows/
│ └── create-user.yml
├── scripts/
│ └── create_user.sh
└── README.md
Step 2: Bash Script
This script handles user creation logic.
#!/bin/bash
set -e
USERNAME=$1
EXPIRY_DATE=$2
if [[ -z "\(USERNAME" || -z "\)EXPIRY_DATE" ]]; then
echo "Usage: $0 <username> <expiry_date>"
exit 1
fi
echo "Creating user: $USERNAME"
echo "Expiry date: $EXPIRY_DATE"
sudo useradd -m -e "\(EXPIRY_DATE" "\)USERNAME"
PASSWORD=$(openssl rand -base64 12)
echo "\(USERNAME:\)PASSWORD" | sudo chpasswd
sudo chage -d 0 "$USERNAME"
sudo chage -l "$USERNAME"
Step 3: GitHub Actions Workflow
name: Create Temporary User
on:
workflow_dispatch:
inputs:
username:
description: "Enter username"
required: true
expiry_date:
description: "Expiry date (YYYY-MM-DD)"
required: true
jobs:
create-user:
runs-on: ubuntu-latest
steps:
- name: Create user via SSH
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.SERVER_IP }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
sudo useradd -m -e "\({{ github.event.inputs.expiry_date }}" "\){{ github.event.inputs.username }}"
sudo chage -l "${{ github.event.inputs.username }}"
Step 4: Configure Secrets
In your GitHub repository:
Settings → Secrets and variables → Actions
Add:
SERVER_IP
SERVER_USER
SSH_PRIVATE_KEY
These values are injected securely during workflow execution.
Step 5: Execute the Workflow
Navigate to the Actions tab
Select the workflow
Click "Run workflow"
Provide username and expiry date
The user will be created on the target server with the defined expiry.
Testing Strategy
You can test the script directly on a GitHub-hosted runner:
runs-on: ubuntu-latest
However, this only validates the logic because the runner is temporary. Any user created there will be removed once the job completes.
For real testing, always validate on a target server via SSH.
Security Considerations
Use SSH key-based authentication instead of passwords
Avoid direct root login; use a controlled sudo user
Use non-interactive shells for service accounts when applicable
Store all sensitive data in GitHub Secrets
Implement approval gates for production workflows
Advanced Enhancements
Once the basic system is working, you can extend it further:
Schedule a job to remove expired users automatically
Integrate approval workflows using GitHub Environments
Add logging to centralized systems like ELK or Azure Monitor
Replace raw SSH execution with configuration management tools like Ansible
Introduce role-based access control for different environments
Real-World Impact
This approach provides:
Consistent and repeatable user provisioning
Reduced operational overhead
Improved auditability
Better alignment with security policies
It also demonstrates a mature DevOps mindset where manual processes are systematically replaced with controlled automation.
Conclusion
User access management is often treated as a routine administrative task, but it has significant security implications. By introducing automation with expiry enforcement, you can reduce risk and improve operational efficiency.
The solution described here is simple to implement but scalable enough to be extended into enterprise-grade workflows.
About the Author
Abhay Patil DevOps Engineer
Blog: https://clouddecode.in LinkedIn: https://www.linkedin.com/in/abhay-patil-devops/
Final Note
Automating small operational tasks like user management can have a significant impact on overall system security and reliability.





