Repository navigation
Create the Android mobile OAuth client id (owner: Altay/backend) #47
Description
Part of #14 (W0 — access and credentials). Owner: Altay/backend.
Outcome
Android mobile has a dedicated OAuth client registration and can prove a full browser sign-in without exposing its bearer callback through Android intent resolution.
TV client IDs 6221 and 6233 are not valid mobile fallbacks. The iOS client ID is not an Android fallback.
Secure transport decision
Use AndroidX Browser Auth Tab with exact redirect putio://auth.
Auth Tab returns the callback URI directly to the Activity that launched it. Android declares no callback intent filter or exported receiver, so another installed app cannot claim the bearer callback through implicit-intent resolution.
The Android implementation must:
- resolve the default Custom Tabs provider
- require that exact provider to advertise Auth Tab support
- pin the launch intent to the verified package
- fail closed when Auth Tab is unavailable
- never fall back to an ordinary Custom Tab
- validate the exact callback endpoint and pending
statebefore accepting a bounded token
Production, nightly, and debug may share putio://auth: no installed package claims the URI, and Auth Tab returns it to the initiating Activity.
Implementation: #65. Shared contract: putio-frontend#34.
Do not substitute the backend's current authorization-code exchange as Proof Key for Code Exchange (PKCE). It requires client_secret and accepts no verifier.
Remaining scope
- Create a dedicated Android mobile OAuth client registration
- Register exact redirect URI
putio://auth - Record the numeric mobile client ID in the shared auth contract
- Add the client ID through the existing BuildConfig input without committing credentials or tokens
- Prove a complete browser sign-in on the mobile harness with the registered client
- Attach the full-round-trip evidence to #65
Acceptance criteria
- No callback receiver or custom-scheme intent filter is exported
- OAuth launches only through a pinned Auth Tab-capable default browser
- Builds without the dedicated client ID remain fail closed
- No mobile variant uses TV IDs
6221/6233or the iOS client ID - Sign-in returns only to the initiating Activity while both installable mobile identities coexist: production/debug
io.put.putio.mobile.debugand nightlyio.put.putio.mobile.nightly.debug. The genericmobileDebugAPK aliases the production/debug application ID, so it cannot be a third installed package - #22 completes a real sign-in, process restart, session restore, and sign-out
Live proof
API 37 Google APIs with Chrome 145.0.7632.218 advertised Auth Tab support. Client 9677 completed consent, returned to the initiating Activity, loaded real Files, restored after force-stop/relaunch, opened a nested folder, and signed out. Coexistence proof: both application IDs were installed, Android reported zero putio://auth handlers, production received the Auth Tab result, nightly remained signed out with separate storage, and production restored Files. Post-auth evidence is attached to #65; no credential or bearer-token surface was captured.
Activity
altaywtf commentedon Aug 29, 2026
Reconciliation update (2026-08-29):
statevalidation does not protect the stolen token.PR #60 does not satisfy or weaken that stop condition.
altaywtf commentedon Aug 29, 2026
Client registration is now wired and documented.
9677, nameput.io Android, callback exactlyputio://auth.4dbfea4wires the public client ID and tests both mobile variants.d07edccrecords the ID in putio-frontend#34.133, which does not advertise Auth Tab support. The app fails closed as designed, so I have not claimed or checked off the full browser round trip.I am leaving this issue open for the successful Auth Tab sign-in, restart/restore, sign-out, and attached evidence.
altaywtf commentedon Aug 30, 2026
Client
9677and exact callbackputio://authare now proven end to end with both installable mobile identities present. Auth Tab returned to the production initiating Activity, nightly remained signed out with isolated storage, production restored its session, and Android exposed zero callback handlers. Evidence: https://attach.uinaf.dev/p/Vn4CkKxiY887tK0vCc75ZQ