Follow-on lab after initial FIDO login

FIDO Lab 4.5 — Blue/Yellow Key Privilege Separation

This lab extends the initial Debian FIDO login build by separating normal identity from privileged authorization. Students log in with a blue key, but must use a separate yellow key to run sudo. The goal is to teach operational trust separation in the same terms used for server administration, privileged access, and recovery planning.

Platform: Debian desktop or lab VM Auth stack: PAM + pam_u2f Audience: students / operators / junior admins Risk: lockout possible without recovery shell
Contents
  1. Lab Overview
  2. Learning Objectives
  3. Blue / Yellow / Red Operational Key Model
  4. Target Architecture
  5. Preflight Safety Requirements
  6. Enroll the Yellow Key for sudo
  7. Configure sudo-Specific PAM
  8. Configure sudo Credential Caching
  9. Test Plan
  10. Rollback and Recovery
  11. Operational Discussion
  12. References

1. Lab Overview

Operational idea: logging in proves identity and presence. Running privileged commands should require a separate authority.

In the first FIDO lab, students configured a FIDO2 authenticator for login. That is useful, but it still collapses a lot of trust into one credential. If the same key can log in and elevate privileges, then compromise, theft, or misuse of that credential may expose both the user session and the administrative path.

This follow-on lab separates those roles. The student logs in with the blue key. The system then requires the yellow key for sudo. This creates step-up authentication for privileged activity and gives students a concrete operational model:

Question Credential Meaning
Who are you? Blue key Identity, login, normal workstation/session access
Are you authorized to elevate? Yellow key Privileged authorization, administrator step-up, intentional elevation
Can the system be recovered? Red key or recovery path Break-glass access, offline recovery, instructor/admin rescue

2. Learning Objectives

Students will implement

  • Separate FIDO trust domains for login and privilege elevation.
  • A central pam_u2f mapping file for the yellow sudo key.
  • A sudo-specific PAM include file that requires the yellow key.
  • A sudoers policy that minimizes credential caching.
  • A test plan proving the blue key alone cannot elevate privileges.

Students will explain

  • The difference between authentication and authorization.
  • Why privileged access should be a separate event from login.
  • Why recovery paths must be engineered before hardening access.
  • How PAM service files allow different rules for different operations.
  • Why cached sudo credentials may weaken step-up authentication.

3. Blue / Yellow / Red Operational Key Model

Blue Key

Operational identity credential.

Used for normal login, unlock, and ordinary user presence.

daily use user-held identity
Yellow Key

Privileged authorization credential.

Used for sudo and other step-up actions. Not used for routine login.

admin use step-up privilege
Red Key

Break-glass recovery credential.

Used only when normal and continuity paths fail. Store offline or under instructor/admin control.

emergency recovery rare use
Teaching note: the colors are operational labels. The physical key color does not matter. What matters is separation of purpose.

4. Target Architecture

1. Login screen or TTY: user authenticates with the blue key.
2. User session: user operates as a non-privileged account.
3. sudo command: PAM policy for sudo requires yellow key authentication.
4. Elevated command: the command runs only after explicit privileged authorization.
5. Recovery path: instructor/admin keeps an alternate route to fix misconfiguration.

Important design choice

This lab uses separate authorization mapping files. The blue key should not appear in the yellow sudo mapping file, and the yellow key should not be enrolled as the ordinary login key. This prevents one credential from satisfying both roles.

/etc/security/fido/
├── blue-login.u2f       # used by the initial login lab, if centrally managed
├── yellow-sudo.u2f      # used only by sudo in this lab
└── red-recovery.u2f     # optional recovery mapping for future labs

5. Preflight Safety Requirements

Do not begin from a fragile system. PAM mistakes can lock students out. Keep a root shell open until the test plan passes.

Assumptions

  • The initial FIDO login lab has already been completed.
  • The blue key can log the student into the system.
  • The student account is already authorized to use sudo.
  • The yellow key is a separate FIDO2 authenticator with a PIN configured.
  • The lab is preferably performed in a VM with a snapshot available.

Open a recovery root shell

Open a terminal and keep this shell open until the end of the lab:

sudo -i

In the root shell, set variables used by the rest of the lab. Replace student with the actual account name.

export TARGET_USER="student"
export FIDO_DIR="/etc/security/fido"
export ORIGIN="pam://fido-lab"

Verify installed tools

dpkg -l libpam-u2f pamu2fcfg | cat
command -v pamu2fcfg
command -v visudo

If the packages are missing:

apt update
apt install -y libpam-u2f pamu2fcfg sudo
Why set a fixed origin? If the origin defaults to the hostname, changes to the VM hostname or cloned images can cause confusing authentication failures. A fixed lab origin such as pam://fido-lab makes the exercise repeatable.

Create the central mapping directory

install -d -m 0750 -o root -g root "$FIDO_DIR"

6. Enroll the Yellow Key for sudo

In this section, students register the yellow key into a mapping file that will be used only by the sudo PAM service. Do not insert the blue key during this step.

Generate the yellow-key mapping

Run this as root from the recovery shell. Insert the yellow key when prompted and touch it when it flashes.

pamu2fcfg \
  -u "$TARGET_USER" \
  -o "$ORIGIN" \
  -i "$ORIGIN" \
  > "$FIDO_DIR/yellow-sudo.u2f"

Secure the mapping file

chown root:root "$FIDO_DIR/yellow-sudo.u2f"
chmod 0640 "$FIDO_DIR/yellow-sudo.u2f"
ls -l "$FIDO_DIR/yellow-sudo.u2f"
sed 's/:.*$/:<credential material hidden>/' "$FIDO_DIR/yellow-sudo.u2f"

Expected shape:

student:<credential material hidden>
Instructor check: the file should contain the target username followed by credential material. It should not contain the blue-key credential unless you intentionally added it, which defeats the lab objective.

7. Configure sudo-Specific PAM

The key trick is that Linux PAM applies policy per service. Login, screen unlock, SSH, and sudo can each have different PAM stacks. We will add a small include file and call it from /etc/pam.d/sudo.

Create a PAM include file for yellow-key sudo

cat > /etc/pam.d/fido-yellow-sudo <<EOF
#%PAM-1.0
#
# FIDO Lab 4.5 — yellow-key privilege elevation
#
# This file is included by /etc/pam.d/sudo.
# It requires the yellow FIDO key for sudo authorization.
#
# cue: prompt the user to touch the authenticator
# pinverification=1: require FIDO2 PIN verification where supported
# userpresence=1: require physical touch/presence
# origin/appid: fixed lab origin to avoid hostname drift problems

auth required pam_u2f.so \
  authfile=/etc/security/fido/yellow-sudo.u2f \
  cue \
  pinverification=1 \
  userpresence=1 \
  origin=pam://fido-lab \
  appid=pam://fido-lab
EOF

chmod 0644 /etc/pam.d/fido-yellow-sudo

Back up the existing sudo PAM file

cp -a /etc/pam.d/sudo "/etc/pam.d/sudo.backup.$(date +%Y%m%d-%H%M%S)"
cat /etc/pam.d/sudo

Edit /etc/pam.d/sudo

Open the file:

nano /etc/pam.d/sudo

Add the following line near the top of the file, before the normal @include common-auth line if that line exists:

auth include fido-yellow-sudo

The resulting file should look similar to this:

#%PAM-1.0

auth include fido-yellow-sudo

@include common-auth
@include common-account
@include common-session-noninteractive
Ordering matters. Place the yellow-key requirement before other authentication includes. Avoid using sufficient for this lab because a sufficient earlier module can bypass later checks.

Do not close the recovery shell

Keep the root shell open. Open a second terminal as the normal student user for testing.

8. Configure sudo Credential Caching

By default, sudo caches successful authentication for a short period. That is convenient, but it weakens the lesson. In this lab, every privileged action should require fresh yellow-key authorization.

Create a lab-specific sudoers drop-in

cat > /etc/sudoers.d/90-fido-yellow-stepup <<EOF
# FIDO Lab 4.5 — require fresh sudo authorization
#
# timestamp_timeout=0 means sudo prompts every time.
# This makes privilege elevation a deliberate step-up event.
Defaults timestamp_timeout=0
EOF

chmod 0440 /etc/sudoers.d/90-fido-yellow-stepup
visudo -cf /etc/sudoers.d/90-fido-yellow-stepup
visudo -c
Operational point: a long-lived root shell such as sudo -i or sudo su - can undermine the “authorize each privileged action” model. For this teaching lab, prefer one-command sudo tests instead of persistent root sessions.

9. Test Plan

Pass condition: the student can log in with the blue key, but cannot run sudo unless the yellow key is present and authorized.

Test 1 — Confirm normal user context

In a normal student terminal:

whoami
id
groups

Expected result: the shell belongs to the student user, not root.

Test 2 — Attempt sudo with no yellow key

Remove the yellow key. Leave the blue key available if the student normally uses it.

sudo -k
sudo whoami

Expected result: sudo should fail because the yellow key is unavailable.

Test 3 — Attempt sudo with blue key only

Insert only the blue key.

sudo -k
sudo whoami

Expected result: sudo should still fail. The blue key is a login credential, not a privilege credential.

Test 4 — Attempt sudo with yellow key

Insert the yellow key.

sudo -k
sudo whoami

Expected result:

root

Test 5 — Confirm fresh authorization is required

sudo whoami
sudo whoami

Expected result: both commands should require authentication because timestamp_timeout=0 disables the normal convenience window.

Test 6 — Verify login still works

Log out or switch to a TTY and verify that normal login still uses the blue-key path from the first lab. Do this only after sudo testing passes and the root recovery shell remains available.

10. Rollback and Recovery

Fast rollback from the open root shell

# Remove the sudo PAM include line
sed -i '/auth include fido-yellow-sudo/d' /etc/pam.d/sudo

# Disable the lab sudoers drop-in
mv /etc/sudoers.d/90-fido-yellow-stepup /root/90-fido-yellow-stepup.disabled 2>/dev/null || true

# Validate sudoers
visudo -c

Restore a known-good sudo PAM file

List backups:

ls -1 /etc/pam.d/sudo.backup.*

Restore the selected backup:

cp -a /etc/pam.d/sudo.backup.YYYYMMDD-HHMMSS /etc/pam.d/sudo

VM recovery

If the system is a VM and the auth stack is badly damaged, revert to the snapshot taken before this lab. Label recommended snapshots:

01-known-good-after-fido-login
02-before-yellow-sudo-lab
03-yellow-sudo-working

11. Troubleshooting

Symptom Likely Cause Check
sudo accepts the blue key Blue credential was accidentally added to yellow-sudo.u2f, or sudo is using the wrong authfile. Inspect /etc/pam.d/fido-yellow-sudo and regenerate the yellow mapping.
sudo never prompts for the key PAM include missing, ordering problem, or sudo timestamp cache still valid. Run sudo -k, then inspect /etc/pam.d/sudo.
sudo succeeds repeatedly without prompting Sudo credential cache is still active. Check /etc/sudoers.d/90-fido-yellow-stepup and run sudo -k.
Yellow key is ignored Wrong origin/appid, key not enrolled, or wrong user in mapping file. Compare ORIGIN, username, and mapping file path.
Prompt appears confusing or blank Display manager or terminal prompt behavior may hide PAM text until Enter is pressed. Test from a TTY and consider adding cue and clear lab instructions.
System is locked out PAM stack was broken and no recovery shell was kept open. Use VM snapshot, rescue boot, or instructor recovery path.
Unclear which key/module actually rejected the attempt The table above tells you where to look, not what PAM itself said. sudo journalctl -g pam_u2f --since "5 minutes ago"sudo isn't a systemd unit, so filter by grepping the message text, not -u.
Watch it happen live. Run sudo journalctl -f in a spare terminal before attempting sudo with each key in the Test Plan above — the blue-key-only and no-key failures in Tests 2 and 3 show up there in real time, with the exact module and reason, instead of just "sudo: 1 incorrect password attempt."

12. Operational Discussion

Authentication is not authorization

Login proves that the user is allowed to start a session. It does not automatically mean the user should be allowed to modify system state. Privilege elevation should be a separate, deliberate event.

Why the yellow key matters

The yellow key resists several common operational failures: unattended sessions, stolen laptop access, hijacked terminals, misused SSH sessions, and over-broad daily credentials. It creates a second decision point before the system crosses into administrative authority.

Why recovery matters

Security mechanisms that cannot be recovered safely become availability failures. The red-key or break-glass concept teaches students that resilient security includes recovery design, documented custody, and tested procedures.

Lab questions

  1. What failure does a blue-only FIDO design still permit?
  2. What changes when sudo requires the yellow key?
  3. Should the yellow key be held by the same person as the blue key in a production environment?
  4. What logs would you review after unauthorized sudo attempts?
  5. What would a red-key procedure look like in a classroom, server room, or enterprise environment?

13. Instructor Notes

Recommended classroom sequence

  1. Start from a known-good VM with blue-key login already working.
  2. Have students snapshot before changing PAM.
  3. Require students to keep a root recovery shell open.
  4. Have students enroll yellow only after explaining operational separation.
  5. Run no-yellow, blue-only, and yellow-present tests in that order.
  6. Only then let students log out and test graphical login again.

Assessment checklist

  • Student can explain blue/yellow/red roles without mentioning literal token color.
  • Student can identify which PAM service controls sudo.
  • Student can show that blue login still works.
  • Student can show that blue alone cannot satisfy sudo.
  • Student can show that yellow satisfies sudo.
  • Student can show that sudo prompts every time.
  • Student can describe rollback steps.

14. Appendix: Optional Hardening Extensions

Limit persistent root shells

The lab teaches one-command privilege elevation. Persistent root shells are useful for recovery but can weaken the operational model. For future labs, consider discussing policies that limit sudo -i, sudo su -, or unrestricted shell escapes.

Separate admin accounts

A production-style extension is to use one account for ordinary login and a separate admin account for elevated maintenance. The blue key authenticates the ordinary user; the yellow key authorizes the admin path.

SSH follow-on

A later lab can use a FIDO-backed SSH key for remote login while still requiring the yellow key for local sudo. This reinforces the idea that remote access and privilege elevation are different control points.

LUKS and Secure Boot follow-on

A later recovery-focused lab can introduce the red key as part of LUKS enrollment, Secure Boot recovery, or instructor-held break-glass access.

15. References