newerkey notes
// devops · 19 June 2026 · 5 min read
DevOps · part 2

Setting Up a Temporary User with an Expiry Date

Silent failure, ISO 8601, and why automation over human memory is the right mental model for access control.

linux users access-control security fundamentals

Part of my #DevOpsFromZero series — documenting real KodeCloud tasks with the commands, the reasoning, the mistakes, and the principles behind every decision.


The Task

Create a user named mariyam on App Server 3. Set the expiry date to 2027-02-17, ensuring the user is created in lowercase as per standard protocol.


Why Would You Ever Need a User with an Expiry Date?

Some users don’t need permanent access. Think of auditors, contractors, or project members brought in for a fixed duration. Once their engagement ends, their access should end with it.

Think of it like giving a contractor a visitor badge that automatically stops working on their last day — rather than depending on someone to cut access who may forget or not be available.

This is automation over human memory. Systems shouldn’t rely on someone remembering to revoke access. Setting an expiry date enforces it automatically, with no manual intervention required.

Real-world cases where this matters:

  • An external auditor who needs read access for two weeks
  • A contractor joining for a fixed-term project
  • An internal team member temporarily elevated for a specific task

The Infrastructure

DetailValue
Hostnamestapp03
SSH Userbanner
ssh banner@stapp03

Step-by-Step: What I Did

1. Connect and Check Context

whoami
# banner

Not root — sudo will be needed for user management.

2. Create the User with an Expiry Date

The useradd command supports the -e flag to set an account expiry date:

sudo useradd -e 2027-02-17 mariyam

No output. No errors. But — as the previous task taught me — that doesn’t mean it worked correctly.

3. Verify the Expiry Date

/etc/passwd stores shell and home directory information, but not account ageing details. For that, use chage:

sudo chage -l mariyam

Output:

Last password change                : Jun 19, 2026
Password expires                    : never
Password inactive                   : never
Account expires                     : Feb 17, 2027
Minimum number of days between password change  : 0
Maximum number of days between password change  : 99999
Number of days of warning before password expires: 7

The Account expires line confirms the date was set correctly. Task complete. ✅


The Mistake: Silent Failure and Wrong Date Format

This is the most important part of this task.

I tested what happens when you pass the date in the wrong format — YYYY-DD-MM instead of YYYY-MM-DD:

sudo useradd -e 2027-28-03 ravi

No error. The command completed silently. But when verified:

sudo chage -l ravi
# Account expires : Apr 03, 2029

Linux didn’t reject the wrong format. It silently interpreted it differently and set a completely unintended expiry date — two years off.

This is one of the most dangerous categories of bugs in engineering: silent failure. No warning. No error. Just wrong behaviour quietly running in production.

Always use YYYY-MM-DD. Always verify with chage -l after creation. Never trust a clean exit code alone.


Why YYYY-MM-DD? The ISO 8601 Standard

The -e flag expects dates in ISO 8601 format — YYYY-MM-DD. This isn’t arbitrary:

  • No ambiguity: 04-03-2027 could mean April 3rd or March 4th depending on where you’re from. 2027-04-03 means exactly one thing everywhere.
  • Lexicographical sorting: Dates starting with the year sort correctly as plain text.
  • Big-endian consistency: Year → Month → Day goes from largest to smallest unit.

When in doubt: year first, always.


A Note on chage Permissions

Running chage -l without sudo returns a permission error:

chage -l mariyam
# chage: Permission denied.

Account ageing information is privileged. You need sudo — or root — to read it.


Key Concepts Recap

ConceptWhat It Means
Account expiryThe date after which a user can no longer log in
useradd -eSets the expiry date at user creation
chage -lDisplays account ageing information for a user
ISO 8601The YYYY-MM-DD date standard used by Linux
Silent failureA command that completes without error but produces unintended behaviour
Automation over memorySystems enforce access revocation — not humans

Closing Thought

Day 1 taught me: not every mistake requires deletion — modify deliberately.

Day 2 adds: no error doesn’t mean correct behaviour. Silent failures are the hardest bugs to catch because they don’t announce themselves.

Verify everything. The two seconds it takes to run chage -l is cheaper than debugging an account that expired two years too late — or two years too early.


Part of my #DevOpsFromZero series — documenting real KodeCloud tasks with the commands, the reasoning, the mistakes, and the principles behind every decision.

linux users access-control security fundamentals

// newerkey notes

Engineering notes on Linux, infrastructure, automation, and platform systems — written as I learn and build.

about these notes