Skip to content

DO NOT MERGE: Require an organization key and store short-lived tokens - #1181

Draft
ericmj wants to merge 1 commit into
mainfrom
organization-short-lived-tokens
Draft

DO NOT MERGE: Require an organization key and store short-lived tokens#1181
ericmj wants to merge 1 commit into
mainfrom
organization-short-lived-tokens

Conversation

@ericmj

@ericmj ericmj commented Jun 16, 2026

Copy link
Copy Markdown
Member

Follow-up to the deprecations in #1179 — this is the breaking change that removes the deprecated paths. It must ship in a release after the one that carries the deprecation warnings, not together with them. Draft until then.

What changes

  • mix hex.organization auth ORGANIZATION now requires --key. Without it, the task raises and points to mix hex.user auth (development) or mix hex.organization key … generate (CI).
  • mix hex.organization auth ORGANIZATION --key KEY now exchanges the key for a short-lived token immediately and stores only the token, never the key. The exchange also verifies the key grants access to the organization.
  • Organization repositories no longer authenticate with a stored API key. They use the cached short-lived token (from auth --key) or, failing that, the user's mix hex.user auth authentication. A stored auth_key left in hex.config by an older client is ignored.
  • HEX_REPOS_KEY no longer grants access to organization repositories — authenticate per organization with auth --key instead.
  • When neither a valid cached token nor user authentication is available for an organization repository, the client prints how to authenticate instead of silently failing.

Scope / compatibility

  • The base hexpm repository is unchanged, including trusted mirrors authenticated with HEX_REPOS_KEY. Full removal of HEX_REPOS_KEY is intentionally out of scope here because it is also used for mirror authentication.
  • The client_credentials exchange itself is unchanged, so CI keeps working: a job runs mix hex.organization auth ORGANIZATION --key $KEY and fetches with the resulting token. Since that exchange issues no refresh token, the token must be re-obtained after it expires (~30 min) — fine for a typical CI job, and the intended friction for a human pasting a key on a workstation.

Follow-up (separate, later)

The hexpm server should eventually reject the exchange of a user-owned key for repository scopes (returning invalid_scope), so the constraint reaches clients that are pinned to old Hex versions. That is deliberately deferred — it is a server-side breaking change to be timed against customer comms, and it is not part of this PR.

@ericmj ericmj changed the title Require an organization key and store short-lived tokens DO NOT MERGE: Require an organization key and store short-lived tokens Jun 16, 2026
mix hex.organization auth now requires --key; the key is exchanged for a
short-lived token immediately and only the token is stored, never the key.
Organization repositories no longer authenticate with a stored API key —
they use the cached short-lived token or the user's OAuth authentication —
and HEX_REPOS_KEY no longer grants access to organization repositories.

For development, mix hex.user auth grants access to all your organizations.
The base hexpm repository (including trusted mirrors authenticated with
HEX_REPOS_KEY) is unchanged.
@ericmj
ericmj force-pushed the organization-short-lived-tokens branch from 5c94711 to dbe0b86 Compare June 16, 2026 19:05
brweber2 added a commit to Cobenian/.github that referenced this pull request Aug 28, 2026
)

Hex >= 2.5.0 warns "Authenticating to the cobenian repository with a stored
key is deprecated and will be removed" on every deps.get/hex.audit in every
repo with private Cobenian deps. The warning's own CI advice is verbatim the
command this step already runs, which makes it look like a live defect and
invites two wrong fixes: rotating HEX_ORG_KEY, or switching to HEX_REPOS_KEY.

Verified against the Hex 2.5.1 source that neither helps. The sole trigger is
`repo_config.auth_key != nil` for a `hexpm:<org>` repo, in
Hex.Repo.build_hex_core_config/3 (lib/hex/repo.ex:325); the key's type, age
and permissions are never inspected, and `hex.organization auth --key` is
exactly what stores auth_key (lib/mix/tasks/hex.ex:280). HEX_REPOS_KEY only
selects the sibling :env branch, which is deprecated too. The non-deprecated
path is OAuth, whose token has no env var (lib/hex/state.ex:18) and is written
only by the interactive `mix hex.user auth` device flow.

Upstream owns it: hexpm/hex#1207 (merged after 2.5.1 shipped) stops the
warning for organization-owned keys, and hexpm/hex#1181 deliberately preserves
this command through the breaking change. This step is already the
forward-compatible form, so this commit is comment-only — no behaviour change,
and no reason to pin Hex, which would only hold the warning still.

Two Hex 2.6 items that are NOT settled are recorded for follow-up: whether
HEX_ORG_KEY is organization-owned or user-owned (only the former keeps
working), and the ~30 min no-refresh token's auth-immediately-before-fetch
requirement, which this workflow satisfies but product Dockerfiles must too.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant