Skip to content

Add GitHub Packages Maven publishing workflow#7

Merged
antspriggs merged 4 commits into
masterfrom
PS-4489-v2
Apr 7, 2026
Merged

Add GitHub Packages Maven publishing workflow#7
antspriggs merged 4 commits into
masterfrom
PS-4489-v2

Conversation

@antspriggs
Copy link
Copy Markdown
Contributor

@antspriggs antspriggs commented Apr 7, 2026

Summary

  • Applies maven-publish plugin to :sdk and configures a release publication (me.id.auth:android-auth-sample-code) targeting https://maven.pkg.github.com/IDme/android-auth-sample-code
  • Version is passed at release time via -PreleaseVersion (e.g. ./gradlew :sdk:publishReleasePublicationToMavenLocalRepository -PreleaseVersion=1.0.0)
  • Publishing to GitHub Packages is handled by release.yml via curl, with build provenance attestations

Test plan

  • Verify Gradle sync succeeds with the maven-publish plugin applied
  • Run ./gradlew :sdk:publishReleasePublicationToMavenLocalRepository -PreleaseVersion=0.1.0 locally to confirm artifacts land in ~/.m2
  • Trigger release.yml via workflow_dispatch with a test version and confirm the package appears at https://github.com/IDme/android-auth-sample-code/packages

🤖 Generated with Claude Code

antspriggs and others added 2 commits March 27, 2026 09:29
Fixes all 4 Critical and 5 High findings, plus 5 of 6 Medium and all 3
Low findings from the pre-release security audit.

Critical:
- [#1] State validation is now unconditional; missing state throws
  StateMismatch, closing the CSRF / authorization code injection vector
- [#2] Public IDmeAuth constructor now requires Context and defaults to
  EncryptedCredentialStore; CredentialStore demoted to internal
- [#3] JWKSClient cache fields are @volatile and all access is serialised
  through a Mutex, eliminating the race condition
- [#4] policies() sends credentials via HTTP Basic Auth header instead of
  GET query parameter, keeping the client secret out of server logs

High:
- [#5] Demo network_security_config.xml removes user-cert trust and sets
  cleartextTrafficPermitted=false
- [#6] iss and aud JWT claims are now mandatory; tokens that omit either
  throw JWTClaimInvalid instead of silently passing
- [#7] JWTValidator validates nbf with 30-second clock skew tolerance and
  applies the same skew window to exp
- [#8] IDmeAuthManager replaces the single CompletableDeferred with a
  ConcurrentHashMap keyed by state; IDmeAuth passes state as sessionId
  so callbacks cannot be routed to the wrong flow
- [#9] extractJSON is now suspend and calls JWTValidator before decoding,
  ensuring userinfo JWT signatures are verified before claims are exposed

Medium:
- [#10] Log.isEnabled flag (default false) gates all SDK log output to
  prevent credential leakage in release builds
- [#11] Redirect URI validation rejects http/https/javascript/file/data
  schemes in IDmeAuth, AuthorizationRequest, and GroupsRequest
- [#12] clearSync() cancels the refresh deferred before nulling state,
  reducing the window for concurrent-write races
- [#13] expiresIn is coerced to [0, 86400] seconds before multiplication,
  preventing integer-overflow-induced negative expiry timestamps
- [#14] AuthViewModel extends AndroidViewModel (provides Context to
  IDmeAuth); clientSecret is only forwarded in OAUTH mode

Low:
- [#15] secure-pipeline-ast.yml pinned to immutable commit SHA instead
  of mutable @master ref
- [#17] Demo release build enables minification
- [#18] Base64URL.decode() throws IDmeAuthError.InvalidJWT on failure
  instead of returning null; JWTDecoder call sites cleaned up accordingly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Apply maven-publish plugin to :sdk with release publication (com.idme:idme-auth-sdk)
- Configure GitHubPackages repository using GITHUB_TOKEN
- Add GROUP and VERSION_NAME to gradle.properties
- Add publish.yml workflow triggered on GitHub Release or workflow_dispatch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@antspriggs antspriggs requested review from a team as code owners April 7, 2026 17:32
@service-idme-github
Copy link
Copy Markdown

service-idme-github commented Apr 7, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

- Accept master's release.yml and build.yml workflows (comprehensive publishing
  with build attestations and curl-based GitHub Packages upload)
- Resolve sdk/build.gradle.kts conflict: use master's me.id.auth:idme-auth-sample
  coordinates and version from -PreleaseVersion flag instead of gradle.properties
- Remove redundant publish.yml (superseded by release.yml)
- Remove GROUP/VERSION_NAME from gradle.properties (version is passed at release time)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
antspriggs added a commit that referenced this pull request Apr 7, 2026
Fixes all 4 Critical and 5 High findings, plus 5 of 6 Medium and all 3
Low findings from the pre-release security audit.

Critical:
- [#1] State validation is now unconditional; missing state throws
  StateMismatch, closing the CSRF / authorization code injection vector
- [#2] Public IDmeAuth constructor now requires Context and defaults to
  EncryptedCredentialStore; CredentialStore demoted to internal
- [#3] JWKSClient cache fields are @volatile and all access is serialised
  through a Mutex, eliminating the race condition
- [#4] policies() sends credentials via HTTP Basic Auth header instead of
  GET query parameter, keeping the client secret out of server logs

High:
- [#5] Demo network_security_config.xml removes user-cert trust and sets
  cleartextTrafficPermitted=false
- [#6] iss and aud JWT claims are now mandatory; tokens that omit either
  throw JWTClaimInvalid instead of silently passing
- [#7] JWTValidator validates nbf with 30-second clock skew tolerance and
  applies the same skew window to exp
- [#8] IDmeAuthManager replaces the single CompletableDeferred with a
  ConcurrentHashMap keyed by state; IDmeAuth passes state as sessionId
  so callbacks cannot be routed to the wrong flow
- [#9] extractJSON is now suspend and calls JWTValidator before decoding,
  ensuring userinfo JWT signatures are verified before claims are exposed

Medium:
- [#10] Log.isEnabled flag (default false) gates all SDK log output to
  prevent credential leakage in release builds
- [#11] Redirect URI validation rejects http/https/javascript/file/data
  schemes in IDmeAuth, AuthorizationRequest, and GroupsRequest
- [#12] clearSync() cancels the refresh deferred before nulling state,
  reducing the window for concurrent-write races
- [#13] expiresIn is coerced to [0, 86400] seconds before multiplication,
  preventing integer-overflow-induced negative expiry timestamps
- [#14] AuthViewModel extends AndroidViewModel (provides Context to
  IDmeAuth); clientSecret is only forwarded in OAUTH mode

Low:
- [#15] secure-pipeline-ast.yml pinned to immutable commit SHA instead
  of mutable @master ref
- [#17] Demo release build enables minification
- [#18] Base64URL.decode() throws IDmeAuthError.InvalidJWT on failure
  instead of returning null; JWTDecoder call sites cleaned up accordingly

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Aligns Maven coordinates with the repository name:
me.id.auth:android-auth-sample-code:<version>

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@antspriggs antspriggs merged commit bf7bed2 into master Apr 7, 2026
2 checks passed
@antspriggs antspriggs deleted the PS-4489-v2 branch April 7, 2026 17:52
gclaro-idme pushed a commit that referenced this pull request Apr 15, 2026
* Address pre-release security audit findings (all Critical + High)

Fixes all 4 Critical and 5 High findings, plus 5 of 6 Medium and all 3
Low findings from the pre-release security audit.

Critical:
- [#1] State validation is now unconditional; missing state throws
  StateMismatch, closing the CSRF / authorization code injection vector
- [#2] Public IDmeAuth constructor now requires Context and defaults to
  EncryptedCredentialStore; CredentialStore demoted to internal
- [#3] JWKSClient cache fields are @volatile and all access is serialised
  through a Mutex, eliminating the race condition
- [#4] policies() sends credentials via HTTP Basic Auth header instead of
  GET query parameter, keeping the client secret out of server logs

High:
- [#5] Demo network_security_config.xml removes user-cert trust and sets
  cleartextTrafficPermitted=false
- [#6] iss and aud JWT claims are now mandatory; tokens that omit either
  throw JWTClaimInvalid instead of silently passing
- [#7] JWTValidator validates nbf with 30-second clock skew tolerance and
  applies the same skew window to exp
- [#8] IDmeAuthManager replaces the single CompletableDeferred with a
  ConcurrentHashMap keyed by state; IDmeAuth passes state as sessionId
  so callbacks cannot be routed to the wrong flow
- [#9] extractJSON is now suspend and calls JWTValidator before decoding,
  ensuring userinfo JWT signatures are verified before claims are exposed

Medium:
- [#10] Log.isEnabled flag (default false) gates all SDK log output to
  prevent credential leakage in release builds
- [#11] Redirect URI validation rejects http/https/javascript/file/data
  schemes in IDmeAuth, AuthorizationRequest, and GroupsRequest
- [#12] clearSync() cancels the refresh deferred before nulling state,
  reducing the window for concurrent-write races
- [#13] expiresIn is coerced to [0, 86400] seconds before multiplication,
  preventing integer-overflow-induced negative expiry timestamps
- [#14] AuthViewModel extends AndroidViewModel (provides Context to
  IDmeAuth); clientSecret is only forwarded in OAUTH mode

Low:
- [#15] secure-pipeline-ast.yml pinned to immutable commit SHA instead
  of mutable @master ref
- [#17] Demo release build enables minification
- [#18] Base64URL.decode() throws IDmeAuthError.InvalidJWT on failure
  instead of returning null; JWTDecoder call sites cleaned up accordingly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add GitHub Packages Maven publishing workflow

- Apply maven-publish plugin to :sdk with release publication (com.idme:idme-auth-sdk)
- Configure GitHubPackages repository using GITHUB_TOKEN
- Add GROUP and VERSION_NAME to gradle.properties
- Add publish.yml workflow triggered on GitHub Release or workflow_dispatch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Rename artifactId to android-auth-sample-code

Aligns Maven coordinates with the repository name:
me.id.auth:android-auth-sample-code:<version>

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add Sonatype Maven Central publishing support

- Add Dokka plugin for Javadoc JAR generation (required by Sonatype)
- Add sources JAR task (required by Sonatype)
- Apply signing plugin with in-memory PGP key support for CI
- Complete POM metadata: url, licenses, developers, and SCM (required by Sonatype)
- Wire Dokka + nexus-publish plugin into root buildscript classpath
- Configure Sonatype OSSRH staging repository via nexus-publish plugin
- Add Sonatype publish step to release workflow using five new secrets:
  SONATYPE_USERNAME, SONATYPE_PASSWORD, SIGNING_KEY_ID, SIGNING_KEY, SIGNING_PASSWORD

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Nat Ray <nathaniel.ray@id.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants