3.0 KiB
3.0 KiB
TASK-002A: Implement the OAuth PKCE protocol core
Status: complete Owner: Codex Reviewer: Claude
Outcome
Provide a deterministic, Android-independent OAuth authorization contract that generates fresh PKCE/state values, requests only approved read scopes, and strictly validates callbacks before any authorization code can be exchanged.
Writable paths
app/src/main/java/com/ubisam/ubgitea/core/auth/protocol/app/src/test/java/com/ubisam/ubgitea/core/auth/protocol/docs/decisions/002-oauth-security.mdtasks/002-oauth-spike.mdtasks/002a-oauth-protocol-core.mdtasks/002b-oauth-android-integration.md
Acceptance criteria
- A fresh cryptographically random verifier and state are generated for every authorization attempt.
- PKCE uses SHA-256 and unpadded Base64 URL encoding with method
S256. - Authorization requests use HTTPS, the registered client ID and redirect URI, and only approved read scopes.
- Callback validation requires an exact redirect scheme, host, effective port, and path.
- Callback validation rejects missing, duplicated, mismatched, or expired state before accepting code or error parameters.
- Missing, blank, or duplicated codes and malformed query encoding are rejected.
- OAuth denial is represented separately from malformed callbacks.
- No client secret, token, Android type, or logging appears in the protocol package.
- Focused tests cover URL construction, freshness, PKCE vectors, scope, redirect validation, state, expiry, denial, code, and malformed input.
Security and privacy
This package must remain pure and must never persist or log authorization codes, tokens, verifier values, or state values.
Required checks
./gradlew assembleDebug
./gradlew testDebugUnitTest
./gradlew lintDebug
Evidence
Recorded on 2026-08-25 using JDK 17 and Android SDK 36:
- Focused OAuth protocol tests — 21 tests, 0 failures, 0 errors.
./gradlew assembleDebug— passed../gradlew testDebugUnitTest— passed; 43 tests across 9 suites, 0 failures, 0 errors../gradlew lintDebug— passed.- Sensitive-pattern scan excluding generated and Git metadata — no assigned client secret, token, password, or private-key value found.
git diff --check— passed.- Automatic string representations for transaction, request, authorization code, and denial results redact sensitive values.
- Actual browser, App Link, token exchange, Keystore, and identity verification remain in TASK-002B.
Review findings
- P2 verifier grammar — fixed by enforcing the RFC 7636 unreserved ASCII character set and 43–128 character length; adversarial tests added.
- P2 callback pollution/encoding — fixed by rejecting conflicting response keys and duplicate recognized parameters, and using strict UTF-8 percent decoding; adversarial tests added.
- P3 time arithmetic overflow — fixed with saturating comparison boundaries and
Long.MIN_VALUE/Long.MAX_VALUEtests. - Independent re-review confirmed all findings closed with no remaining P0-P3 findings.