The write APIs in #35 (IAS3 upload, metadata write, Tasks, reviews write) all need credentials, so this comes first. This is the auth layer they build on.
How archive.org auth works
- The credential is an S3 access/secret key pair. Sign requests with
Authorization: LOW <access>:<secret>. Metadata write also accepts the keys as access= / secret= form fields.
- Keys can be fetched programmatically: POST
email + password to https://archive.org/services/xauthn/?op=login. The JSON response returns values.s3.access, values.s3.secret, the logged-in-user / logged-in-sig cookies, and screenname. No HTML scraping needed.
- Or the user copies their keys straight from https://archive.org/account/s3.php and pastes them in.
- The official
internetarchive Python lib splits these: config.py does the one-time xauthn login, auth.py just assumes keys exist and attaches the header.
The split
Consume vs. acquire. IAKit knows how to talk to IA; it never becomes the owner of the secret.
In scope (required):
Optional, defensible:
Out of scope (app's job, not the library's):
- Storing keys/cookies (Keychain). IAKit returns them, the app persists them.
- Login UI, "remember me", biometric gating.
- Being the session manager / cookie jar. It attaches what you give it, it doesn't own lifecycle.
Notes
- The sensitive part isn't the S3 keys, it's that programmatic login handles the account's primary password, and IA has no delegated-auth flow to avoid it. Keeping storage and UI out of the library means the password only ever lives inside that one login call. Pasting keys from s3.php skips passwords entirely, so write support can ship with no login helper at all.
- For LMA, pin down which write actions we actually need first. Reviews/favorites may be cookie-auth website endpoints rather than IAS3, in which case the cookies from xauthn matter more than the S3 keys.
The write APIs in #35 (IAS3 upload, metadata write, Tasks, reviews write) all need credentials, so this comes first. This is the auth layer they build on.
How archive.org auth works
Authorization: LOW <access>:<secret>. Metadata write also accepts the keys asaccess=/secret=form fields.email+passwordtohttps://archive.org/services/xauthn/?op=login. The JSON response returnsvalues.s3.access,values.s3.secret, thelogged-in-user/logged-in-sigcookies, andscreenname. No HTML scraping needed.internetarchivePython lib splits these:config.pydoes the one-time xauthn login,auth.pyjust assumes keys exist and attaches the header.The split
Consume vs. acquire. IAKit knows how to talk to IA; it never becomes the owner of the secret.
In scope (required):
LOW access:secret. Mirrors how the read layer injects no credentials and just takes a query. Small and testable.Optional, defensible:
login(email:password:)that wraps the xauthn POST and returns the keys + cookies. Stores nothing, holds the password only for the request, never logs it. Worth it so consumers don't hand-roll that one call, and since xauthn is a clean JSON endpoint it isn't scraping.Out of scope (app's job, not the library's):
Notes