Anisette Bootstrap and Apple Account Authentication
This runbook explains how to verify the private Anisette service, authenticate an Apple account for FindMy, and save the resulting account state for the tracker fetcher services.
When To Use This
Use this procedure when:
- the tracker fetcher cannot authenticate against Apple FindMy
ANISETTE_SERVERis timing out- you need to refresh
/data/account.json - you are bootstrapping a new staging or production account
What This Does
The bootstrap flow:
- Starts a temporary ECS task in the
tracker-restapi-staging-cluster - Opens an ECS Exec shell inside that task
- Verifies that the private Anisette endpoint is reachable
- Runs
scripts/authenticate_findmy.py - Stores the authenticated account in
/data/account.json
The bootstrap task uses the same private network path as the worker services, so it is the correct place to test Anisette connectivity.
Prerequisites
- AWS credentials with permission to run ECS tasks and use ECS Exec
AWS_PROFILE=glimpse-stagingfor the staging environmentenable_anisette = truein the target Terraform environment- Anisette service deployed and running in ECS
- The
tracker-fetcher-2task definition and EFS mount available
Bootstrap Procedure
Run the bootstrap script from your shell:
AWS_PROFILE=glimpse-staging ./scripts/bootstrap_anisette_account.sh
The script will:
- Read Terraform outputs from
infra/envs/staging - Start a temporary ECS task in
tracker-restapi-staging-cluster - Wait for the ECS Exec agent to become ready
- Open an interactive shell in the container
- Show the commands you need to run inside the task
Inside the ECS shell, export the expected environment and run the auth script:
export ANISETTE_SERVER=http://anisette-v3.anisette-v3.local:6969
export ACCOUNT_STORE_PATH=/data/account.json
python scripts/authenticate_findmy.py
Verify Anisette First
If you want to verify the connectivity, before entering credentials, confirm the endpoint is reachable from inside the ECS task:
curl -v http://anisette-v3.anisette-v3.local:6969
Expected success looks like this:
* Host anisette-v3.anisette-v3.local:6969 was resolved.
* IPv4: 10.40.0.146
* Trying 10.40.0.146:6969...
* Connected to anisette-v3.anisette-v3.local (10.40.0.146) port 6969
< HTTP/1.1 200 OK
< Server: vibe.d/2.13.3
< Implementation-Version: anisette-v3-server v2.2.2
If the curl call times out:
- the Anisette service may not be running
- ECS may not have the right egress rule to the private service port
- the task may be outside the VPC path that can reach the private DNS name
Authenticate Apple
When the Anisette test passes, run the authentication script.
The script will prompt for:
- Apple ID email
- Apple ID password
- 2FA method selection
- verification code
Example flow:
Authenticating...
============================================================
2-Factor Authentication Required
============================================================
Available authentication methods:
0 - Trusted device
1 - SMS
Select method number: 1
Requesting authentication code...
Code sent! Check your device/SMS.
Enter the 6-digit code:
Submitting code...
✓ 2FA successful!
On success, the account is written to:
/data/account.json
Restart The Worker
After the account file is saved, restart or redeploy the tracker fetcher service so it reloads the new account state.
For staging:
aws ecs update-service \
--profile glimpse-staging \
--region eu-west-2 \
--cluster tracker-restapi-staging-cluster \
--service tracker-restapi-staging-tracker-fetcher-2 \
--force-new-deployment
If your deployment flow uses a different service name, update the --service argument accordingly.
Troubleshooting
curl hangs or times out
- Confirm the Anisette ECS service is running
- Check the service events for task stop/start messages
- Verify the ECS security group allows traffic to the private service port
- Check CloudWatch logs for the Anisette task
authenticate_findmy.py times out before 2FA
- The Anisette endpoint is not reachable
- The private service discovery record may exist, but nothing is listening on port
6969
authenticate_findmy.py completes but warns about unclosed sessions
- Those warnings are emitted by the upstream
findmy/aiohttpstack during shutdown - They do not prevent the account from being saved