# How MFA Cookie Authentication Works in docker-icloudpd: Lifecycle and Expiration Handling

> Learn how docker-icloudpd MFA cookie authentication works. Understand cookie lifecycle and expiration handled by the X-APPLE-WEBAUTH-USER token stored in /config/.

- Repository: [boredazfcuk/docker-icloudpd](https://github.com/boredazfcuk/docker-icloudpd)
- Tags: deep-dive
- Published: 2026-02-26

---

**docker-icloudpd authenticates to Apple's iCloud servers using a temporary MFA cookie generated by the icloudpd binary, which is stored in `/config/` and expires approximately every 30 days when the `X-APPLE-WEBAUTH-USER` token reaches its embedded expiry timestamp.**

The `boredazfcuk/docker-icloudpd` container wraps the iCloud Photos Downloader to automate photo backups, relying on cookie-based authentication to persist multi-factor authentication (MFA) sessions across container restarts. The implementation relies on specific cookie fields parsed by shell functions in [`sync-icloud.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/sync-icloud.sh) to validate sessions and detect when Apple's security policies force a re-authentication cycle.

## How the MFA Cookie Is Generated

When the container initializes or runs a re-authentication command, the [`sync-icloud.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/sync-icloud.sh) script invokes the icloudpd binary with the `--auth-only` flag to trigger Apple's MFA flow. Specifically, lines 618–621 execute:

```bash
/opt/icloudpd/bin/icloudpd --username ${apple_id} \
                           --cookie-directory /config \
                           --auth-only \
                           --domain ${auth_domain}

```

This command initiates a login request to Apple's iCloud servers. The user must approve the sign-in on a trusted Apple device and provide the six-digit MFA code. Upon successful authentication, Apple returns HTTP cookies which the binary stores in `/config/${cookie_file}`. 

The presence of the `X-APPLE-WEBAUTH-HSA-TRUST` cookie entry signals that the MFA challenge was satisfied. The script logs successful authentication when this token is detected (lines 623–625), confirming that subsequent API calls will use the cached credentials.

## Cookie Validation Before Each Sync

Before attempting to download photos, the container validates the existing cookie through the `check_multifactor_authentication_cookie()` function defined in [`sync-icloud.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/sync-icloud.sh) (lines 740–767). This validation occurs in distinct phases:

1. **File existence check** – The script verifies that `/config/${cookie_file}` exists (lines 740–744).

2. **Pre-approval state detection** – If the cookie contains exactly one `X-APPLE-DS-WEB-SESSION-TOKEN` and **no** `X-APPLE-WEBAUTH-HSA-TRUST` entry, the script recognizes that MFA approval is still pending (lines 750–752).

3. **Post-approval validation** – After user approval, the script searches for the `X-APPLE-WEBAUTH-USER` cookie entry (line 756). It extracts the `expires` attribute from this field (line 758) to determine the cookie's remaining lifetime.

If the expiry date is in the future, the script sets `valid_mfa_cookie=true` and logs the number of days remaining (lines 764–767), allowing the sync process to proceed.

## Expiration Detection and Automated Renewal

When the current date meets or exceeds the extracted expiry timestamp, the cookie is considered invalid. The container handles expiration through two mechanisms:

- **Immediate expiration** – If the expiry date has passed, [`sync-icloud.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/sync-icloud.sh) deletes the stale cookie file (lines 767–769) and logs an authentication error. The container's restart policy or an external auto-heal service then triggers a fresh initialization cycle.

- **Proactive warning system** – For cookies entering their final 24 hours of validity, the script detects the "final-day" condition (lines 791–802) and dispatches a notification to alert the user that re-authentication is required imminently.

The [`reauth.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/reauth.sh) helper script can be invoked manually to force this cycle by removing the existing cookie and triggering a new MFA flow without waiting for the automatic detection.

## Health Check Integration

The auxiliary [`healthcheck.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/healthcheck.sh) script provides independent monitoring of the cookie state without executing a full sync. Lines 56–68 parse the same cookie fields—`X-APPLE-DS-WEB-SESSION-TOKEN` and `X-APPLE-WEBAUTH-USER`—to calculate remaining days until expiration. 

This allows Docker's health check mechanism to report container status accurately:

```bash

# Example: Check cookie status manually inside the container

docker exec icloudpd grep "X-APPLE-WEBAUTH-USER" /config/<sanitized_apple_id>

# Output shows expiry: expires="2026-03-28T12:00:00Z"

```

When the health check detects an imminent expiration, it returns a non-healthy status, enabling orchestration tools to restart the container before the cookie becomes invalid.

## What Causes MFA Cookie Expiration

Cookie expiration in docker-icloudpd is driven by Apple's security infrastructure rather than container configuration. The iCloud service deliberately limits MFA cookie lifetimes to approximately **30 days** as a security measure against persistent unauthorized access.

The specific technical trigger is the `expires` attribute embedded within the `X-APPLE-WEBAUTH-USER` cookie value. When the container parses this timestamp and finds it predates the current system time, it treats the authentication context as expired. At this point, no API requests will succeed until the user completes a fresh MFA flow—approving the login on an Apple device and entering the verification code—to generate a new cookie with a refreshed expiry date.

## Summary

- **Cookie generation** occurs via `/opt/icloudpd/bin/icloudpd --auth-only`, creating files in `/config/` containing `X-APPLE-WEBAUTH-HSA-TRUST` upon successful MFA.
- **Validation logic** in [`sync-icloud.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/sync-icloud.sh) checks for `X-APPLE-WEBAUTH-USER` and parses its expiry timestamp to determine session validity.
- **Expiration triggers** when the embedded `expires` attribute (typically ~30 days) is reached, causing automatic deletion of the cookie file.
- **Health monitoring** via [`healthcheck.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/healthcheck.sh) independently tracks remaining cookie lifetime to enable proactive container restarts.
- **Manual intervention** through [`reauth.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/reauth.sh) or container restart initiates a new MFA flow when cookies expire or become corrupted.

## Frequently Asked Questions

### Where does docker-icloudpd store the MFA cookie?

The container stores the MFA cookie file at `/config/${cookie_file}`, where the filename corresponds to a sanitized version of the configured Apple ID. This path is set via the `--cookie-directory /config` argument passed to the icloudpd binary during initialization.

### How long does an MFA cookie remain valid?

According to the source code analysis of the cookie parsing logic, Apple issues MFA cookies with an expiration window of approximately **30 days**. The exact date is encoded in the `expires` attribute of the `X-APPLE-WEBAUTH-USER` cookie entry, which the scripts parse to calculate remaining validity.

### What happens when the MFA cookie expires?

When [`sync-icloud.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/sync-icloud.sh) detects an expired timestamp (lines 767–769), it removes the cookie file from `/config/` and logs an authentication failure. The container then relies on its restart policy or external orchestration to trigger a new authentication cycle, requiring the user to approve the login on an Apple device and enter the MFA code.

### Can I force a cookie refresh before expiration?

Yes. You can manually trigger re-authentication by executing the [`reauth.sh`](https://github.com/boredazfcuk/docker-icloudpd/blob/main/reauth.sh) script inside the container or by removing the cookie file and restarting the container. This forces the `icloudpd --auth-only` command to run immediately, generating a fresh cookie with a new 30-day expiration window without waiting for the automatic health check to fail.