IT support tooling for account auditing and authentication log analysis. Detect security issues in Active Directory / Entra ID exports and identify suspicious login patterns in syslog auth files.
This project is built for practical help desk and junior sysadmin workflows: checking account-export hygiene and spotting suspicious SSH authentication patterns before they become support tickets. It demonstrates CSV handling, log parsing, structured JSON reporting, and testable command-line automation with no runtime dependencies.
-
Account Auditing: Scan CSV exports of user accounts for security misconfigurations
- Missing or duplicate usernames
- Accounts with MFA disabled
- Invalid email addresses
- Inactive or stale accounts (no login in 90+ or 180+ days)
- Never-logged-in active accounts
-
Auth Log Analysis: Parse syslog-format auth logs and detect anomalies
- Brute-force attempts from a single IP (5+ failures in 10 minutes)
- Repeated failures per user account
- Structured JSON reporting
python -m pip install -e ".[dev]"
supportops audit-accounts tests/fixtures/sample_accounts.csv
supportops analyze-logs tests/fixtures/sample_auth.log --year 2026
python -m pytest -qThe fixture files are fake and are included only to make the tool easy to test locally.
Install from source:
pip install -e .With development dependencies:
pip install -e ".[dev]"Audit a CSV export of user accounts:
supportops audit-accounts accounts.csvOutput is JSON by default. To save to a file:
supportops audit-accounts accounts.csv --output report.jsonFilter to a specific severity level:
supportops audit-accounts accounts.csv --severity critical
supportops audit-accounts accounts.csv --severity warning
supportops audit-accounts accounts.csv --severity infoScan an auth.log file for suspicious patterns:
supportops analyze-logs auth.logIf your logs use month/day format without a year, specify the year:
supportops analyze-logs auth.log --year 2025Save the report to a file:
supportops analyze-logs auth.log --output log_report.jsonThe audit-accounts command expects a CSV with these columns:
username,display_name,email,enabled,last_login,mfa_enabled,groups
Example:
username,display_name,email,enabled,last_login,mfa_enabled,groups
jdoe,Jane Doe,jdoe@corp.example,true,2026-06-01T14:30:00Z,true,Admins;IT
bgates,Bill Gates,bgates@corp.example,false,,true,Salesusername: Account login name (required, must be unique)display_name: Full nameemail: Email address (validated for basic format)enabled: "true", "1", "yes", "false", "0", "no"last_login: ISO-8601 datetime or empty for never logged inmfa_enabled: "true", "1", "yes", "false", "0", "no"groups: Semicolon-separated list of group names
The analyze-logs command parses standard syslog auth entries from SSH:
Jun 14 10:05:00 host sshd[1234]: Accepted password for jdoe from 192.168.1.1 port 22 ssh2
Jun 14 10:06:15 host sshd[1234]: Failed password for jdoe from 10.0.0.100 port 22 ssh2
Supported patterns:
- SSH login success:
Accepted passwordorAccepted publickey - SSH login failure:
Failed passwordorauthentication failure - Unsupported lines are silently ignored
{
"total_accounts": 10,
"issue_counts": {
"critical": 2,
"warning": 3,
"info": 0
},
"issues": [
{
"username": "jdoe",
"severity": "critical",
"code": "MFA_DISABLED",
"detail": "Active account has MFA disabled."
}
]
}Issue codes and severity levels:
MFA_DISABLED(critical): Active account lacks MFAINACTIVE_ACCOUNT(critical): No login in 180+ daysDUPLICATE_USERNAME(critical): Username appears twiceMISSING_USERNAME(critical): Empty username fieldSTALE_ACCOUNT(warning): No login in 90+ daysNEVER_LOGGED_IN(warning): Active account, never usedINVALID_EMAIL(warning): Email doesn't matchuser@domain.tldformat
{
"total_events": 150,
"event_type_counts": {
"login_success": 140,
"login_failure": 10
},
"anomaly_count": 1,
"anomalies": [
{
"username": "(multiple)",
"kind": "brute_force_ip",
"detail": "IP 10.0.0.100 had 5 failed logins within 10 minutes starting 2026-06-14T10:00:00+00:00.",
"count": 5
}
]
}Anomaly kinds:
brute_force_ip: 5+ failed logins from one IP in 10 minutesrepeated_failures: User account with 5+ failed attempts (any time window)
Commands return 1 if critical issues or anomalies are found, 0 otherwise.
supportops audit-accounts accounts.csv
echo $? # 1 if any critical issues, 0 if cleanRun the test suite:
pytestRun a specific test class:
pytest tests/test_core.py::TestAuditAccountsRun tests with verbose output:
pytest -vMIT