In the previous lesson, we established that confidentiality ensures only authorized eyes see sensitive data. But how do we determine who is authorized in the first place? Enter the AAA framework: Authentication (proving identity), Authorization (granting permissions), and Accounting (logging actions for non-repudiation). When a rogue employee at Tesla exported gigabytes of Autopilot source code in 2021, the investigation relied entirely on accounting logs to establish non-repudiation β proving that a specific authenticated user performed specific actions that authorization should have prevented.
Authentication is the process of verifying an identity claim. The three classic authentication factors are: something you know (password, PIN), something you have (smart card, YubiKey, phone), and something you are (fingerprint, face, retina). Multi-factor authentication (MFA) combines two or more of these categories. A password plus a one-time code from an authenticator app constitutes MFA; two passwords do not, because both fall under 'something you know' and share the same vulnerability profile.
Biometrics are not secrets. You cannot rotate your fingerprint after a breach. Treat biometric authentication as a convenience factor, not a high-assurance secret. Always pair biometrics with a second factor for sensitive systems.
# Simple MFA simulation: verifying a TOTP code alongside a password
import pyotp
import hashlib
# User's stored credentials (hashed password, TOTP secret)
stored_password_hash = hashlib.sha256(b"CorrectHorseBatteryStaple").hexdigest()
totp_secret = "JBSWY3DPEHPK3PXP" # Base32-encoded TOTP secret
def authenticate(password: str, totp_code: str) -> bool:
# Factor 1: Something you know
if hashlib.sha256(password.encode()).hexdigest() != stored_password_hash:
print("[FAIL] Password incorrect β authentication denied")
return False
# Factor 2: Something you have (TOTP generator)
totp = pyotp.TOTP(totp_secret)
if not totp.verify(totp_code):
print("[FAIL] TOTP code invalid or expired β authentication denied")
return False
print("[SUCCESS] Multi-factor authentication passed")
return True
# Test with correct credentials
authenticate("CorrectHorseBatteryStaple", totp.now())
# [SUCCESS] Multi-factor authentication passedAuthentication confirms identity; authorization defines permissions. The principle of least privilege dictates that users should have the minimum access necessary to perform their job functions β and nothing more. Role-Based Access Control (RBAC) maps permissions to roles, not individuals. Attribute-Based Access Control (ABAC) extends this with contextual attributes like time-of-day, device posture, and geolocation. A payroll specialist should have write access to salary tables during business hours from a corporate device, but never from a coffee shop VPN at 3 AM.
The `/etc/shadow` file demonstrates classic Unix discretionary access control (DAC). Only the root user (UID 0) has read-write access; members of the `shadow` group have read-only access (needed by authentication daemons). All other users are denied. This is authorization, not authentication β even if you prove you are `alice`, the filesystem permission bits authorize or deny your access to this specific resource.
Accounting (sometimes called Auditing) is the systematic logging of authentication events, authorization decisions, and user actions. Non-repudiation is the property that prevents a user from plausibly denying they performed an action. Together, they form the evidentiary backbone of incident response. When properly implemented, accounting logs answer: Who accessed what? From where? When? What did they do? And β critically β can they deny it? Digital signatures, timestamps from trusted time sources, and append-only log architectures all strengthen non-repudiation.
π‘ Non-repudiation requires cryptographic binding. A plaintext log entry saying 'User Alice deleted record #4567' is trivially forgeable. But a log entry signed with Alice's private key and timestamped by a trusted authority is cryptographically non-repudiable.
| AAA Component | Question Answered | Primary Mechanisms | Failure Consequence |
|---|---|---|---|
| Authentication | Who are you? | Passwords, MFA, biometrics, certificates | Impersonation, unauthorized access |
| Authorization | What can you do? | RBAC, ABAC, file permissions, IAM policies | Privilege escalation, data leakage |
| Accounting | What did you do? | Audit logs, digital signatures, SIEM | Inability to investigate, no non-repudiation |
β οΈ Never implement authentication and authorization in the same code module. The 'single point of decision' anti-pattern means a bug in your auth logic can grant both identity bypass and admin permissions simultaneously. Enforce separation of concerns.
Verify exercises to earn β 100 XP and unlock next lab level.