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

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 to validate sessions and detect when Apple's security policies force a re-authentication cycle.

When the container initializes or runs a re-authentication command, the sync-icloud.sh script invokes the icloudpd binary with the --auth-only flag to trigger Apple's MFA flow. Specifically, lines 618–621 execute:

/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.

Before attempting to download photos, the container validates the existing cookie through the check_multifactor_authentication_cookie() function defined in 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 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 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 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:


# 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.

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 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 independently tracks remaining cookie lifetime to enable proactive container restarts.
  • Manual intervention through reauth.sh or container restart initiates a new MFA flow when cookies expire or become corrupted.

Frequently Asked Questions

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.

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.

When 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.

Yes. You can manually trigger re-authentication by executing the 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →