3  Auth & Authorization Basics

Understanding Identity Verification and Permission Control in IoT

3.1 Learning Objectives

By completing this chapter, you will be able to:

  • Distinguish between authentication and authorization as separate but related security functions
  • Explain the AAA framework (Authentication, Authorization, Accounting) and its role in enterprise security
  • Identify common authentication methods for IoT devices including tokens, certificates, and biometrics
  • Understand role-based access control principles and how they apply to IoT systems
  • Recognize security anti-patterns such as hardcoded credentials and missing authorization
Prerequisites

Before starting this chapter, you should be familiar with:

  • Basic security terminology (credentials, permissions, access)
  • Fundamental networking concepts (client-server, protocols)
  • Why IoT security matters (see Cyber Security Methods)

“Think of authentication like the bouncer at a concert,” Sammy the Sensor explained. “The bouncer checks your ticket to make sure you are really a ticket holder. That is authentication – proving your identity. But just having a ticket does not mean you can go backstage!”

Max the Microcontroller continued. “Authorization is the VIP list. Even after the bouncer lets you in, a separate list determines whether you get regular seats, VIP seats, or backstage access. In IoT, authentication verifies a device’s identity, and authorization determines what data it can access and what actions it can perform.”

“The AAA framework adds a third piece: Accounting,” Lila the LED said. “That is like the security cameras and entry logs that record who went where and when. Authentication: who are you? Authorization: what can you do? Accounting: what did you do? All three work together to create a complete security system.”

“A common mistake is confusing these two,” Bella the Battery warned. “Some systems authenticate users but then give everyone full access – that is like a building where everyone with a badge can enter every room. Or worse, some systems check permissions but never verify identity – that is like restricting rooms but never checking badges at the front door. You need BOTH authentication AND authorization working together!”


3.2 Authentication vs Authorization: Understanding the Difference

Two concepts that are often confused but are fundamentally different:

Two-step access control flowchart showing user presenting credentials to authentication step which verifies identity and answers 'Who are you?', then if authenticated proceeds to authorization step which checks permissions and answers 'What can you do?', leading to either access granted or access denied
Figure 3.1: The two-step access control process: authentication verifies identity, authorization determines permissions
Concept Question Answered Example Failure Mode
Authentication “Who are you?” RFID card, password, fingerprint “I don’t recognize you”
Authorization “What can you do?” Admin vs user privileges “You don’t have permission”

Key insight: Authentication must happen BEFORE authorization. You cannot determine what someone is allowed to do until you know who they are.

Think of a library:

  1. Authentication is like showing your library card at the front desk. The librarian scans it to confirm you are a registered member (you are who you claim to be).
  2. Authorization is what your membership level allows. A standard membership lets you borrow books; a research membership also gives you access to the restricted archives.

Your library card proves your identity (authenticated member), but your membership TYPE determines what resources you can access (authorization level).

Try It: Authentication vs Authorization Flow

Simulate access requests to see how authentication and authorization work as separate steps. Select a user and a resource, then observe which step grants or denies access.


3.3 The AAA Framework

Enterprise security systems use the “AAA” framework to structure access control:

Component Question IoT Example Production Example
Authentication Who are you? Card ID lookup, device certificate OAuth login, biometrics
Authorization What can you do? Access level check, capability flags RBAC, ABAC policies
Accounting What did you do? Audit log entries SIEM, CloudTrail

All three components are essential:

  • Authentication without authorization means everyone gets full access once identified
  • Authorization without accounting means you cannot investigate incidents
  • Authentication without accounting means you cannot trace who performed actions

Try It: AAA Framework Event Simulator

Generate security events and see how Authentication, Authorization, and Accounting each play a different role. Toggle components on and off to observe what breaks when one is missing.


3.4 Common Authentication Methods for IoT

IoT devices use various authentication mechanisms depending on constraints:

3.4.1 Token-Based Authentication

Devices present tokens (RFID cards, API keys, JWT tokens) that prove identity:

Token Type Use Case Pros Cons
RFID/NFC Physical access control Fast, contactless Can be cloned
API Keys Cloud service access Simple to implement Long-lived, hard to rotate
JWT Tokens Session authentication Short-lived, self-contained Require refresh logic
X.509 Certificates Device identity Cryptographically strong Requires PKI infrastructure

3.4.2 Challenge-Response Authentication

Instead of sending a password over the network (where it could be intercepted), challenge-response protocols work differently. The server sends a random value called a nonce (number used once), and the device must compute a cryptographic response using the nonce combined with its secret key. The server performs the same computation and compares results. If they match, the device proved it possesses the correct secret – without ever transmitting it.

The security of this approach depends entirely on nonces being unique and unpredictable. The following question explores what happens when this requirement is violated:

3.4.3 Multi-Factor Authentication (MFA)

Combining multiple authentication factors provides defense in depth:

Factor Type Example IoT Application
Something you have Badge, phone, hardware token Device certificate in secure element
Something you know Password, PIN Admin override codes
Something you are Fingerprint, face scan Biometric access control

Try It: Multi-Factor Authentication Strength Calculator

Select which authentication factors are active and see how the combined security strength changes. Each factor category reduces the probability of unauthorized access by orders of magnitude.


3.5 Role-Based Access Control (RBAC)

RBAC assigns permissions to roles, and roles to users:

RBAC architecture diagram with three layers: Users layer showing Alice, Bob, and Carol; Roles layer showing Admin Role, Engineer Role, and Operator Role; Permissions layer showing Read/Write All, Read Sensors Write Logs, and Read Only, with arrows showing users assigned to roles and roles assigned to permissions

Role-Based Access Control diagram showing three users (Alice Admin, Bob Engineer, Carol Operator) assigned to roles (Admin Role, Engineer Role, Operator Role) which are then assigned permissions (Read/Write All, Read Sensors Write Logs, Read Only), demonstrating indirect permission assignment through roles


3.6 Security Anti-Patterns to Avoid

3.6.1 Hardcoded Credentials

Embedding credentials in firmware creates fleet-wide vulnerabilities:

3.6.2 Authentication Without Authorization

Objective: Demonstrate how IoT devices authenticate with an MQTT broker using username/password credentials versus certificate-based TLS mutual authentication. This shows why certificate-based auth is preferred for production IoT.

import hashlib
import hmac
import os
import time

# ── Scenario 1: Username/Password MQTT Authentication ──
# This simulates what happens inside an MQTT broker when a device connects
# with CONNECT packet containing username and password fields.

# Broker's credential store (in production, use salted hashes in a database)
BROKER_CREDENTIALS = {
    "sensor_floor1": hashlib.sha256(b"s3cur3_p@ss_f1").hexdigest(),
    "sensor_floor2": hashlib.sha256(b"s3cur3_p@ss_f2").hexdigest(),
    "gateway_main":  hashlib.sha256(b"gw_m@st3r_k3y").hexdigest(),
}

def mqtt_authenticate(username, password):
    """Simulate MQTT CONNECT authentication at the broker.

    MQTT 3.1.1 return codes:
      RC=0: Connection Accepted
      RC=4: Connection Refused, bad user name or password
      RC=5: Connection Refused, not authorized (valid credentials but lacks permission)
    """
    if username not in BROKER_CREDENTIALS:
        return False, "CONNACK: Bad User Name or Password (RC=4)"
    password_hash = hashlib.sha256(password.encode()).hexdigest()
    if password_hash != BROKER_CREDENTIALS[username]:
        return False, "CONNACK: Bad User Name or Password (RC=4)"
    return True, "CONNACK: Connection Accepted (RC=0)"

# Test authentication scenarios
test_cases = [
    ("sensor_floor1", "s3cur3_p@ss_f1", "Valid credentials"),
    ("sensor_floor1", "wrong_password",  "Wrong password"),
    ("unknown_device", "any_password",   "Unknown device"),
]

print("=== MQTT Username/Password Authentication ===")
for username, password, description in test_cases:
    success, response = mqtt_authenticate(username, password)
    status = "OK" if success else "FAIL"
    print(f"  [{status}] {description}: {response}")

# ── Scenario 2: Why Certificates Are Better ──
# Compare security properties of each method

print("\n=== Authentication Method Comparison ===")
comparison = [
    ("Property",               "Username/Password",      "X.509 Certificate"),
    ("Credential per device",  "Often shared (bad)",     "Unique per device"),
    ("Revocation",             "Change all passwords",   "Revoke single cert (CRL)"),
    ("Replay protection",      "Requires TLS transport", "Built-in (TLS handshake)"),
    ("Brute-force risk",       "Yes (dictionary attack)","No (private key never sent)"),
    ("Rotation complexity",    "High (fleet-wide)",      "Low (auto-renew via EST)"),
]
for row in comparison:
    print(f"  {row[0]:<25} {row[1]:<25} {row[2]}")

What to Observe:

  1. Username/password auth is simple but shares credentials across device classes – compromising one device exposes others
  2. The broker returns standardized MQTT CONNACK return codes (RC=0 success, RC=4/5 failure)
  3. Certificate-based auth avoids transmitting secrets entirely – the private key never leaves the device
  4. For fleets of 10,000+ devices, certificate revocation (CRL/OCSP) is far more practical than rotating shared passwords

Objective: Create and verify JSON Web Tokens (JWTs) to authenticate IoT device requests, demonstrating how token-based auth works in practice.

import hmac
import hashlib
import json
import base64
import time

def base64url_encode(data):
    """URL-safe base64 encoding without padding"""
    return base64.urlsafe_b64encode(data).rstrip(b'=').decode()

def base64url_decode(s):
    """URL-safe base64 decoding with padding restoration"""
    s += '=' * (4 - len(s) % 4)
    return base64.urlsafe_b64decode(s)

def create_jwt(device_id, role, secret_key, expires_in=3600):
    """Create a JWT for an IoT device"""
    header = {"alg": "HS256", "typ": "JWT"}
    payload = {
        "device_id": device_id,
        "role": role,
        "iat": int(time.time()),
        "exp": int(time.time()) + expires_in
    }

    header_b64 = base64url_encode(json.dumps(header).encode())
    payload_b64 = base64url_encode(json.dumps(payload).encode())
    signing_input = f"{header_b64}.{payload_b64}"

    signature = hmac.new(
        secret_key.encode(), signing_input.encode(), hashlib.sha256
    ).digest()
    signature_b64 = base64url_encode(signature)

    return f"{header_b64}.{payload_b64}.{signature_b64}"

def verify_jwt(token, secret_key):
    """Verify a JWT and return the payload if valid"""
    parts = token.split(".")
    if len(parts) != 3:
        return None, "Invalid token format"

    signing_input = f"{parts[0]}.{parts[1]}"
    expected_sig = hmac.new(
        secret_key.encode(), signing_input.encode(), hashlib.sha256
    ).digest()
    actual_sig = base64url_decode(parts[2])

    if not hmac.compare_digest(expected_sig, actual_sig):
        return None, "Invalid signature"

    payload = json.loads(base64url_decode(parts[1]))
    if payload.get("exp", 0) < time.time():
        return None, "Token expired"

    return payload, "Valid"

# Gateway's secret key (shared with auth server)
SERVER_SECRET = "iot_gateway_secret_2024"

# Device authenticates and receives a token
token = create_jwt("ESP32_SENSOR_001", "sensor", SERVER_SECRET)
print(f"JWT Token: {token[:60]}...")

# Gateway verifies the token on each request
payload, status = verify_jwt(token, SERVER_SECRET)
print(f"\nVerification: {status}")
print(f"Device ID: {payload['device_id']}")
print(f"Role: {payload['role']}")

# Test with tampered token (attacker changes role to admin)
parts = token.split(".")
fake_payload = json.loads(base64url_decode(parts[1]))
fake_payload["role"] = "admin"
fake_b64 = base64url_encode(json.dumps(fake_payload).encode())
tampered_token = f"{parts[0]}.{fake_b64}.{parts[2]}"

_, tamper_status = verify_jwt(tampered_token, SERVER_SECRET)
print(f"\nTampered token: {tamper_status}")

# Test with wrong secret (rogue gateway)
_, wrong_key_status = verify_jwt(token, "wrong_secret")
print(f"Wrong key: {wrong_key_status}")

What to Observe:

  1. The JWT contains three parts: header, payload, and signature (separated by dots)
  2. The payload is base64-encoded (readable) but the signature prevents modification
  3. Changing even one character in the payload invalidates the signature
  4. Only gateways with the correct secret can issue or verify tokens

Objective: Implement a simple RBAC system demonstrating how different device roles get different permissions.

# Role-Based Access Control for IoT
ROLES = {
    "sensor": {"permissions": ["READ_TEMP", "READ_HUMIDITY", "STATUS"],
               "description": "Read-only sensor device"},
    "actuator": {"permissions": ["READ_TEMP", "STATUS", "SET_THRESHOLD", "ACTIVATE"],
                 "description": "Can read and control outputs"},
    "gateway": {"permissions": ["READ_TEMP", "READ_HUMIDITY", "STATUS",
                                "SET_THRESHOLD", "ACTIVATE", "CONFIG_UPDATE"],
                "description": "Full device management"},
    "admin": {"permissions": ["READ_TEMP", "READ_HUMIDITY", "STATUS",
                              "SET_THRESHOLD", "ACTIVATE", "CONFIG_UPDATE",
                              "FIRMWARE_UPDATE", "FACTORY_RESET"],
              "description": "Full system control"}
}

def check_authorization(device_role, requested_action):
    """Check if a role has permission to perform an action"""
    if device_role not in ROLES:
        return False, f"Unknown role: {device_role}"
    if requested_action in ROLES[device_role]["permissions"]:
        return True, f"AUTHORIZED: {device_role} can {requested_action}"
    return False, f"DENIED: {device_role} cannot {requested_action}"

# Simulate different devices requesting actions
test_cases = [
    ("sensor",   "READ_TEMP",       "Sensor reads temperature"),
    ("sensor",   "FIRMWARE_UPDATE",  "Sensor tries firmware update"),
    ("actuator", "ACTIVATE",         "Actuator triggers output"),
    ("actuator", "FACTORY_RESET",    "Actuator tries factory reset"),
    ("gateway",  "CONFIG_UPDATE",    "Gateway updates config"),
    ("admin",    "FACTORY_RESET",    "Admin resets device"),
]

print("RBAC Authorization Tests:")
print("-" * 55)
for role, action, description in test_cases:
    authorized, message = check_authorization(role, action)
    icon = "PASS" if authorized else "DENY"
    print(f"  [{icon}] {description}")
    print(f"         {message}")

What to Observe:

  1. Sensors can only read data – they cannot control outputs or update firmware
  2. Each role has the minimum permissions needed for its function (least privilege)
  3. Even if a sensor’s credentials are stolen, the attacker can only read data
  4. Only admins can perform destructive operations like factory reset

Objective: This Arduino sketch shows how an ESP32 establishes a TLS connection to an MQTT broker using a client certificate for mutual authentication. This is the production-grade approach for IoT device identity.

// ESP32 TLS Mutual Authentication - MQTT Client
// Requires: PubSubClient + WiFiClientSecure libraries
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>

// WiFi credentials
const char* ssid = "IoT-Network";
const char* password = "wifi_password";

// MQTT Broker (TLS on port 8883)
const char* mqtt_server = "broker.example.com";
const int   mqtt_port = 8883;

// Root CA certificate (verify broker identity)
const char* ca_cert = R"EOF(
-----BEGIN CERTIFICATE-----
MIIBxTCCAWugAwIBAgIUd3Y...  // Your CA cert here
-----END CERTIFICATE-----
)EOF";

// Device client certificate (device identity)
const char* client_cert = R"EOF(
-----BEGIN CERTIFICATE-----
MIIBpDCCAUqgAwIBAgIUa7F...  // Unique per device
-----END CERTIFICATE-----
)EOF";

// Device private key (NEVER share -- stored in secure element)
const char* client_key = R"EOF(
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIKz8P9M3...          // Unique per device
-----END EC PRIVATE KEY-----
)EOF";

WiFiClientSecure espClient;
PubSubClient mqtt(espClient);

void setup() {
    Serial.begin(115200);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) delay(500);

    // Configure TLS mutual authentication
    espClient.setCACert(ca_cert);        // Verify broker
    espClient.setCertificate(client_cert); // Prove device identity
    espClient.setPrivateKey(client_key);   // Sign TLS handshake

    mqtt.setServer(mqtt_server, mqtt_port);
}

void loop() {
    if (!mqtt.connected()) {
        // TLS handshake: broker verifies our cert, we verify broker's cert
        if (mqtt.connect("ESP32_SENSOR_001")) {
            Serial.println("Connected with mutual TLS auth");
            mqtt.publish("sensors/floor1/temp", "23.5");
        } else {
            Serial.print("TLS auth failed, rc=");
            Serial.println(mqtt.state());
        }
    }
    mqtt.loop();
    delay(5000);
}

What to Observe:

  1. Three credentials: CA cert (trust anchor), client cert (device identity), private key (proof of possession)
  2. The broker verifies the device’s certificate during TLS handshake – no username/password needed
  3. Each device gets a unique certificate provisioned during manufacturing
  4. If a device is compromised, revoke only its certificate via CRL – other devices are unaffected
  5. The private key should ideally be stored in a hardware secure element (ATECC608A) rather than flash

3.7 Choosing the Right Authentication Method

Different IoT scenarios call for different authentication approaches. This table maps device capabilities to appropriate methods:

If your device/scenario is… Choose… Because…
Severely constrained MCU (<32 KB RAM), private network Pre-shared keys (PSK) Minimal computation, no certificate parsing, pre-provisioned at factory
Constrained MCU (32-256 KB RAM), needs mutual auth X.509 certificates (with hardware key storage) Strong identity, revocable per-device, no shared secrets
Gateway or SBC running Linux OAuth 2.0 + client certificates Standard cloud integration, token refresh, fine-grained scopes
Consumer devices (phones, tablets) accessing IoT OAuth 2.0 + OIDC User-friendly flows, social login, token-based, no device certs
Industrial/enterprise with existing PKI Mutual TLS (mTLS) Leverages existing certificate infrastructure, strongest binding
Large fleet (>10K devices) needing zero-touch onboarding Device Provisioning Service + certificates Automated enrollment, no manual credential distribution
Brownfield devices, no crypto capability API keys + IP allowlisting Pragmatic fallback, but weakest option – plan to upgrade

Quick Decision Flowchart:

  1. Can the device perform asymmetric cryptography (RSA/ECC)? No –> PSK (symmetric only)
  2. Does the device have a hardware secure element (ATECC608, TPM)? Yes –> X.509 client certificates stored in secure element
  3. Is this a human user accessing IoT via app/web? Yes –> OAuth 2.0 with OIDC
  4. Do you have an existing PKI or certificate authority? Yes –> Mutual TLS
  5. Is this a prototype or development environment? Yes –> Username/password is acceptable temporarily; never in production
  6. Default: X.509 certificates for device-to-cloud; OAuth 2.0 for user-to-cloud

Never use hardcoded credentials in production. Even PSK should be unique per device, provisioned during manufacturing, and stored in non-volatile secure storage. Shared credentials across a fleet mean one compromised device exposes all devices.

Try It: IoT Authentication Method Selector

Answer questions about your IoT deployment to get a recommended authentication method. Adjust the parameters to see how device constraints, fleet size, and security requirements change the recommendation.

3.8 Summary

In this chapter, you learned:

  1. Authentication verifies identity (“Who are you?”) while authorization verifies permissions (“What can you do?”)
  2. The AAA framework (Authentication, Authorization, Accounting) provides the structure for enterprise security
  3. Common authentication methods for IoT include tokens, certificates, challenge-response, and multi-factor authentication
  4. Role-based access control assigns permissions to roles, simplifying management
  5. Security anti-patterns like hardcoded credentials and missing authorization create catastrophic vulnerabilities
Key Takeaway

Authentication answers “Who are you?” while Authorization answers “What can you do?”

Always implement both. A system that only authenticates gives all authenticated users full access. A system that tries to authorize without authenticating cannot know whose permissions to check.


3.9 Knowledge Check

A warehouse deploys 200 temperature sensors that must authenticate with the gateway every hour to prove they are genuine devices, not rogue sensors injecting false data.

Challenge-Response Protocol:

  1. Sensor initiates connection: Sends device ID SENSOR_042

  2. Gateway sends challenge: Random 128-bit nonce 0x8F2A...C1D3

  3. Sensor computes response:

    // Sensor has pre-shared secret KEY_042 (32 bytes)
    uint8_t response[32];
    hmac_sha256(KEY_042, nonce, response);
    // Response = HMAC-SHA256(KEY_042, 0x8F2A...C1D3)
  4. Gateway verifies:

    // Gateway has database of all sensor keys
    uint8_t expected[32];
    hmac_sha256(lookup_key("SENSOR_042"), nonce, expected);
    if (memcmp(response, expected, 32) == 0) {
        // Authentication success - sensor has correct key
    }

Why this works:

  • Sensor proves possession of secret key WITHOUT transmitting the key
  • Nonce prevents replay attacks (each authentication uses unique challenge)
  • Attacker capturing network traffic sees different nonce/response every time

Timing Attack Protection:

// BAD: Returns early if first byte mismatches
bool verify_insecure(uint8_t* response, uint8_t* expected) {
    for (int i = 0; i < 32; i++) {
        if (response[i] != expected[i]) return false;  // Early return leaks timing
    }
    return true;
}

// GOOD: Constant-time comparison
bool verify_secure(uint8_t* response, uint8_t* expected) {
    uint8_t diff = 0;
    for (int i = 0; i < 32; i++) {
        diff |= (response[i] ^ expected[i]);  // XOR accumulates differences
    }
    return (diff == 0);  // Always checks all 32 bytes
}

Production Deployment: 200 sensors × 24 authentications/day = 4,800 auth/day. Zero unauthorized sensors detected over 18 months. Average authentication latency: 35ms.

MFA Combination Security Level User Friction IoT Use Case
Password + SMS code Medium High (requires phone, delays) Consumer IoT apps (rare admin actions)
RFID badge + PIN Medium-High Low (common workflow) Physical access control (doors, lockers)
Device cert + biometric High Medium (fingerprint scan) High-security facilities (data centers)
Hardware token + password Very High Medium-High (carry token) Industrial SCADA, critical infrastructure
Push notification + biometric High Low (phone approval) Modern enterprise IoT dashboards

Factor Categories:

  1. Something you have: Badge, phone, hardware token, certificate in secure element
  2. Something you know: Password, PIN, passphrase
  3. Something you are: Fingerprint, face recognition, iris scan

Selection Criteria:

  • Regulatory requirement (PCI DSS, HIPAA) → Hardware token + PIN (strongest)
  • Consumer convenience → Push notification (low friction, high security)
  • Offline operation required → Badge + PIN (no network needed)
  • Critical infrastructure → 3-factor (cert + biometric + PIN)

IoT-Specific Considerations:

  • Device constraints: ESP32 can verify certificates but not generate TOTP codes (limited RTC)
  • Network reliability: SMS codes fail in poor coverage; prefer app-based TOTP
  • Biometrics: Fingerprint sensors cost $3-8, add physical security without network dependency
Common Mistake: Using Role Hierarchy for Non-Hierarchical Permissions

What practitioners do wrong: They assume access control is always hierarchical (ADMIN > USER > GUEST) and assign permissions accordingly. This fails when different roles need different non-overlapping permissions.

Example that fails:

enum Role { GUEST=0, USER=1, ADMIN=2 };

// Assumes: ADMIN has all USER permissions + more
bool authorize(Role userRole, Role requiredRole) {
    return (userRole >= requiredRole);  // WRONG for non-hierarchical permissions
}

Why it fails:

  • Hospital: DOCTOR and NURSE are parallel roles, not hierarchical
    • DOCTOR can prescribe medication (NURSE cannot)
    • NURSE can administer medication (DOCTOR typically doesn’t)
    • Neither role is “higher” than the other
  • Manufacturing: OPERATOR and MAINTENANCE are parallel
    • OPERATOR controls production line
    • MAINTENANCE accesses mechanical systems
    • Neither should have full access to both

Correct approach (capability-based):

const uint16_t CAP_PRESCRIBE_MEDS = 0x01;
const uint16_t CAP_ADMINISTER_MEDS = 0x02;
const uint16_t CAP_ACCESS_MEDICAL_RECORDS = 0x04;

struct User {
    const char* name;
    uint16_t capabilities;
};

User users[] = {
    {"Dr. Smith",  CAP_PRESCRIBE_MEDS | CAP_ACCESS_MEDICAL_RECORDS},
    {"Nurse Jane", CAP_ADMINISTER_MEDS | CAP_ACCESS_MEDICAL_RECORDS},
};

bool authorize(uint16_t userCaps, uint16_t requiredCaps) {
    return (userCaps & requiredCaps) == requiredCaps;
}

Real-world consequence: A 2017 hospital IoT deployment used hierarchical roles where “Physician” > “Nurse” > “Technician”. This gave physicians access to medical equipment calibration controls (technician permission), leading to 3 incidents of accidental re-calibration causing incorrect readings. Post-incident audit mandated capability-based access where equipment calibration is a separate permission bit, not tied to role hierarchy.

HMAC-based challenge-response authentication uses a cryptographic hash function \(H\) with a shared secret key \(K\) to prove possession of \(K\) without transmitting it.

\[\text{Response} = \text{HMAC}(K, \text{Nonce}) = H((K \oplus \text{opad}) \,||\, H((K \oplus \text{ipad}) \,||\, \text{Nonce}))\]

where \(\text{opad} = 0x5c5c...5c\) and \(\text{ipad} = 0x3636...36\) are padding constants.

Working through an example:

Given: IoT sensor authenticates to gateway using HMAC-SHA256 - Shared secret: \(K = \text{32-byte device-specific key}\) - Gateway sends nonce: \(N = \text{0x8F2AC1D3...}\) (16 bytes random) - Hash function: SHA-256 (256-bit output) - Attacker’s computing power: \(10^{12}\) hash operations/second

Step 1: Calculate sensor’s response (simplified)

\[R = \text{HMAC-SHA256}(K, N)\]

Result: 32-byte (256-bit) authentication tag sent to gateway

Step 2: Calculate security against brute force attack

Attacker must guess the 256-bit secret key \(K\). Number of possible keys:

\[\text{Key Space} = 2^{256}\]

Time to brute force with \(10^{12}\) attempts/second:

\[T_{\text{brute force}} = \frac{2^{256}}{10^{12} \text{ attempts/s}}\]

\[T_{\text{brute force}} = \frac{1.16 \times 10^{77}}{10^{12}} = 1.16 \times 10^{65} \text{ seconds}\]

Converting to years (\(3.15 \times 10^7\) seconds/year):

\[T_{\text{years}} = \frac{1.16 \times 10^{65}}{3.15 \times 10^7} \approx 3.7 \times 10^{57} \text{ years}\]

Step 3: Calculate collision probability for nonce reuse

If the same nonce \(N\) is used twice, the attacker can replay the previous valid response. Probability of nonce collision with 128-bit nonces after \(n\) authentications (birthday paradox):

\[P(\text{collision}) \approx \frac{n^2}{2^{129}}\]

For \(n = 1,000,000\) authentications:

\[P(\text{collision}) \approx \frac{(10^6)^2}{2^{129}} = \frac{10^{12}}{6.8 \times 10^{38}} \approx 1.5 \times 10^{-27}\]

Result: HMAC-SHA256 with a 256-bit key is computationally infeasible to brute force (\(3.7 \times 10^{57}\) years). With proper nonce generation (128-bit random), collision probability is negligible (\(1.5 \times 10^{-27}\) for 1 million authentications).

In practice: Challenge-response with HMAC provides strong authentication without transmitting the secret key. Each authentication uses a unique nonce, preventing replay attacks. For IoT devices with pre-provisioned keys, HMAC-SHA256 offers 256-bit security with minimal computational overhead (SHA-256 is hardware-accelerated on most modern MCUs). Never reuse nonces – implement cryptographically secure random number generation for nonce creation.

3.9.1 Interactive: HMAC Security Explorer

Adjust the parameters below to see how key length, attacker speed, and nonce size affect the security of HMAC-based challenge-response authentication.

3.10 Concept Relationships

How Authentication Fundamentals Connect
Core Concept Builds On Enables Common Confusion
Authentication (who) Identity verification Authorization decisions “Is checking permissions authentication?” - No, that’s authorization. Authentication only proves identity
Authorization (what) Successful authentication Access control enforcement “Can’t authentication alone secure a system?” - No. Proving identity doesn’t determine permissions
AAA framework Separation of concerns Complete security architecture “Why three separate components?” - Each serves distinct function: verify (auth), permit (authz), record (accounting)
RBAC Role hierarchies Permission management via roles “Are roles the only way?” - No. Capability-based and attribute-based are alternatives
Token-based auth Credentials Stateless authentication “Are tokens the same as passwords?” - No. Tokens are issued AFTER password authentication

Key Insight: Authentication and authorization are separate security functions that must both be implemented. Knowing WHO someone is (authentication) does not determine WHAT they can do (authorization).

Common Pitfalls

Using the same username/password for all 10,000 devices in a fleet means one compromised device exposes all devices. Each IoT device must have unique credentials, provisioned at manufacturing or first boot, enabling individual device revocation without affecting the fleet.

Many IoT systems verify that a device is who it claims to be (authentication) but then grant all authenticated devices full API access (no authorization). A compromised temperature sensor should not be able to actuate a valve. Always implement both layers.

Credentials embedded in firmware are visible to anyone who extracts the binary with a flash reader or decompiles the firmware. Use secure element storage (ATECC608A, TPM), provisioning services, or at minimum store credentials in separate flash sectors with read protection enabled.

IoT devices deployed for 10 years with certificates that expire in 1 year will become unreachable when certificates expire. Plan for OTA certificate renewal from day one, including device-initiated renewal before expiry and a recovery mechanism for devices that miss the renewal window.

3.11 What’s Next

If you want to… Read this
Start the hands-on lab Lab: Basic Access Control Setup
Implement zero trust security architecture Zero Trust Security
Learn cryptographic authentication and TLS Cyber Security Methods
Understand attacker perspectives Threat Modelling and Mitigation
Explore IoT-specific access control IoT Security Access Control

Now that you understand the fundamentals, put them into practice:

For related security topics:

If you want to… Read this
Implement zero trust security architecture Zero Trust Security
Learn cryptographic authentication and TLS Cyber Security Methods
Understand attacker perspectives Threat Modelling and Mitigation
Explore IoT-specific access control IoT Security Access Control
Practice with hands-on lab Lab: Basic Access Control Setup

Key Concepts

  • Authentication: The process of verifying the claimed identity of a user, device, or service; answers “who are you?”
  • Authorization: The process of determining what an authenticated principal is permitted to do; answers “what are you allowed to do?”
  • Multi-Factor Authentication (MFA): Requiring two or more independent verification factors (something you know, have, or are) to authenticate
  • RBAC (Role-Based Access Control): Assigning permissions to roles and assigning roles to users/devices; simplifies permission management at scale
  • ABAC (Attribute-Based Access Control): Making access decisions based on attributes of the subject, resource, environment, and action; more flexible than RBAC for complex IoT policies
  • Principle of Least Privilege: Every component should have only the minimum permissions required for its function; fundamental to limiting damage from compromised credentials
  • Zero Trust: The security model that assumes no network location is inherently trusted and verifies every request explicitly regardless of origin
In 60 Seconds

Authentication verifies identity (“who are you?”) while authorization determines permissions (“what can you do?”) — in IoT, both must be enforced on every device, every request, and every service endpoint because a compromised device or API without authorization checks can cascade to full system compromise.