Mitigations

August 21, 2026 ยท View on GitHub

This document describes the controls that address identified threats.

Status Legend:

  • Implemented - Control is in place
  • Partial - Control exists but has known gaps
  • Planned - On roadmap but not yet implemented

Identity & Access

Addresses: T1, T4

Authentication

ControlStatusDescription
Email verificationImplementedUsers must verify email addresses for account recovery
Password minimum lengthImplementedMinimum 8 characters, no complexity rules
Leaked password detectionImplementedChecks passwords against HaveIBeenPwned API on login and password change; warns users but allows login
Two-factor authentication (TOTP)ImplementedOptional for login, required for write operations with OAuth
Phishing-resistant 2FA (WebAuthn)PlannedHardware security keys and passkeys
Passwordless authenticationPlannedPasskey-based access methods
OAuth2 Device Authorization GrantImplementedSecure CLI authentication flow. See Client Flows
Login rate limitingImplemented10 attempts per IP per 15 minutes
Mandatory 2FA for maintainersPlannedRequires rebar3 OAuth migration, then disable basic auth; 2FA already required for OAuth write operations
Critical package MFAPartialRequire MFA for maintainers of high-impact packages
Abandoned domain detectionPlannedDetect and disable account recovery via expired email domains
Security notificationsImplementedAlert maintainers about critical account changes via email
Account recovery policyPlannedDocumented procedures for account access restoration

Token Management

ControlStatusDescription
Scoped API tokensImplementedTokens can be scoped by domain (api, repository, package, docs) and resource (read/write, specific repos/packages)
Short-lived OAuth access tokensImplementedAccess tokens expire quickly, refresh tokens for renewal
Token revocationImplementedUsers can revoke tokens at any time
API key expiry datesImplementedAllow setting expiration on API keys
Token prefixingPlannedDistinctive repository identifiers on all tokens
Secret scanning integrationPlannedTokens compatible with third-party secret detection tools with automated revocation
2FA for write operationsImplementedOAuth tokens require 2FA for publishing. See Client Flows

Session Security

ControlStatusDescription
Secure session cookiesImplementedPhoenix default secure cookie configuration
Session timeoutImplementedAutomatic session expiration
Session invalidationImplementedLogout invalidates session server-side
Sudo modeImplementedCritical operations require re-authentication; shorter lifetime than regular session

Publishing Controls

Addresses: T1, T2

Ownership Model

ControlStatusDescription
Package ownership requiredImplementedOnly owners can publish to a package
Owner levelsImplemented"full" (can manage owners) vs "maintainer" (can publish only)
Transfer confirmationImplementedOwnership transfers require confirmation

Audit Trail

ControlStatusDescription
Comprehensive audit loggingImplementedLogs: releases (publish/revert/retire), ownership changes, key operations, password changes, email changes, billing, sessions, 2FA changes
Audit log metadataImplementedIncludes user agent, remote IP, key/token used, user data snapshot
Package audit logsImplementedViewable per-package in dashboard
User audit logsImplementedViewable per-user in dashboard

Version Immutability

ControlStatusDescription
Immutable versionsImplementedPublished versions cannot be modified after grace period
Retirement (not deletion)ImplementedPackages can be retired but not deleted

Supply Chain Integrity

Addresses: T3

Registry Signing

ControlStatusDescription
RSA-PKCS1-SHA512 signaturesImplementedAll registry files are signed
Public key distributionImplementedPublic key bundled with clients
Client signature verificationImplementedClients verify before trusting metadata. See Client Flows

Checksums

ControlStatusDescription
Outer checksum (SHA-256)ImplementedTarball integrity verification
Checksums in signed registryImplementedChecksums protected by registry signature
Client verificationImplementedClients verify checksums before extraction

Build Provenance

ControlStatusDescription
Trusted Publishing (OIDC)PlannedCI provider integration for keyless publishing
Build attestations (SLSA)PlannedCryptographic proof of build origin
Source repository linkingPartialLinks exist but not cryptographically verified

See Supply Chain - Provenance.

Ecosystem Protections

Addresses: T2

Namespace Controls

ControlStatusDescription
Globally unique namesImplementedPackage names are unique across the registry
Reserved namesImplementedCommon names like "hex", "elixir", "erlang", "otp" are reserved
Squatting policiesImplementedNames can be reclaimed if squatted

Typosquatting Detection

ControlStatusDescription
Levenshtein distance checkImplementedDaily job checks new packages against existing names; emails moderators when candidates found
Automated blockingAccepted RiskDetection is alert-only; does not block publishing

Malicious Package Detection

ControlStatusDescription
Malicious package scanningPlannedAutomated scanning of packages for known malicious patterns and file hashes
Malicious package disclosure (OSV)PlannedMalicious packages disclosed to OSV database

Community Reporting

ControlStatusDescription
Report mechanism (UI)PlannedUsers can report suspicious packages via web UI
Report mechanism (CLI)PlannedUsers can report suspicious packages via CLI
Report mechanism (API)PlannedUsers can report suspicious packages via API
Review processPlannedReports are reviewed by operators

Documentation Isolation

Addresses: T5

Origin Separation

ControlStatusDescription
Separate originImplementedDocumentation served from hexdocs.pm, isolated from the registry origin
Per-package origin isolationImplementedEach package's docs served from its own origin so the browser same-origin policy prevents cross-package attacks: public packages at <package>.hexdocs.pm, organization packages at <org>.hexorgs.pm/<package>
No shared authenticationImplementedhexdocs.pm has no access to registry sessions

Content Security

ControlStatusDescription
Content Security PolicyImplementedCSP headers with Sentry violation reporting
README sandboxingImplementedREADMEs rendered in isolated iframe with restricted CSP
Content sanitizationImplementedHTML sanitizer for user-provided content

Infrastructure Security

Addresses: T6

Access Control

ControlStatusDescription
Least privilegePartialInfrastructure access limited to a small set of operators; Kubernetes RBAC enforced; OIDC federation scopes CI service account permissions
Role-based accessImplementedUser roles: "basic", "mod"

See Operations - Access Control.

Security Policy

ControlStatusDescription
Vulnerability disclosure policyImplementedPublished policy allowing security researchers to report issues with legal safe harbor

Network Security

ControlStatusDescription
Service isolationImplementedServices separated where possible
TLS everywhereImplementedAll external communication encrypted

Monitoring

ControlStatusDescription
Security event monitoringImplementedSecurity-relevant events are monitored
CSP violation reportingImplementedCSP violations reported to Sentry
Event transparency logsPlannedPublished activity records enabling anomaly detection
Security infrastructure reviewsPlannedPeriodic assessments of repository systems

Availability

Addresses: T7

Rate Limiting

ControlStatusDescription
API rate limits (authenticated)Implemented500 requests per user per minute
API rate limits (unauthenticated)Implemented100 requests per IP per minute
Organization rate limitsImplemented500 requests per organization per minute
Login rate limitsImplemented10 attempts per IP per 15 minutes
2FA rate limitsImplemented20 attempts per IP per 15 minutes; 5 per session per 10 minutes
Sudo mode rate limitsImplemented5 password attempts per user per 15 minutes; 5 2FA attempts per user per 15 minutes
Device verification limitsImplemented10 per user, 30 per IP per 15 minutes
IP allow/block listsImplementedConfigurable address filtering
Upload size limitsImplementedMaximum package size enforced

CDN

ControlStatusDescription
Fastly CDNImplementedGlobal edge caching for package distribution
Edge cachingImplementedReduces origin load, improves availability

Operational

ControlStatusDescription
Monitoring and alertingImplementedAvailability monitoring in place
Incident responseImplementedDocumented procedures. See Operations - Incident Response

Dependency Security

Addresses: T8

Vulnerability Tracking

ControlStatusDescription
Advisory database integrationPartialHex.pm ingests OSV advisory data, surfaces it on the website, and serves it through the registry; consumed by Hex (Elixir/Mix), not yet by Rebar3 or Gleam
Hex.pm as CNAImplementedCan issue CVEs for Elixir/Erlang packages via EEF CNA

See SDLC - Secure Process.

User Tools

ControlStatusDescription
mix hex.audit (retirement)ImplementedCLI tool checks for retired packages
mix hex.audit (advisories)ImplementedHex (Elixir/Mix) surfaces security advisories affecting resolved dependencies; not yet in Rebar3 or Gleam
Dependency tree visibilityImplementedTransitive dependencies shown in metadata
Security advisories on hex.pmImplementedAdvisories displayed on package pages at /packages/:name/advisories
Hash/version pinningImplementedDependencies can be locked to specific versions and checksums via lock files
SBOM generationImplementedSoftware Bill of Materials documentation
Automated remediationPlannedUpgrade dependencies to resolve known vulnerabilities
Reachability analysisPlannedReduce false positives by determining if vulnerable code paths execute

Dependency Policies

Client-side enforcement of organization-defined policies, currently available in Hex (Elixir/Mix); not yet in Rebar3 or Gleam. A policy is defined on hex.pm under an organization (or on any self-hosted repo), fetched through the registry at resolution time, and used to filter candidate versions before the solver sees them, so blocked versions are simply never selected. See Client Flows for how policies fit into resolution.

ControlStatusDescription
Policy fetched from registryImplementedActive policy resolved via Hex config precedence (HEX_POLICY env var, mix.exs, then global config); one active policy per project
Cooldown ruleImplementedBlocks newly published versions until they reach a minimum age; effective cooldown is the strictest of local config and the policy
Advisory ruleImplementedBlocks versions with security advisories at or above a severity threshold (or with any advisory)
Retirement ruleImplementedBlocks versions retired for the configured reasons
Package/version overridesImplementedPackage and version scoped allow, deny, advisory, retirement, and policy-cooldown overrides; comments are available on every type
Finding-scoped policy overridesImplementedAdvisory and retirement overrides accept one current identifier or reason without accepting unrelated findings; cooldown overrides don't disable local cooldown configuration
Lockfile exemptionImplementedVersions already locked are exempt from filtering, so re-resolution keeps a locked-but-now-blocked entry instead of failing
Policy visibilityImplementedPublic policies are fetchable anonymously; private policies require authentication to the owning organization
Fail-closed enforcementImplementedMalformed config, fetch failures (without a cached copy), or 404/401 abort resolution rather than resolving unenforced
mix hex.policy show / whyImplementedSummarize the active policy and explain per-version why each is allowed or blocked
Policy-aware dependency auditImplementedAudits locked advisory and retirement findings against policy overrides and restriction thresholds

Ecosystem Health

Addresses: T9

Package Metadata

ControlStatusDescription
Last activity indicatorsImplementedShows when package was last updated
Retirement statusImplementedPackages can be marked as retired. See Package Metadata

Community Signals

ControlStatusDescription
Download statisticsImplementedShows package popularity
Maintenance activityImplementedVisible update history

Succession Planning

ControlStatusDescription
Ownership transferImplementedMechanism to transfer packages
Abandoned package adoptionPartialProcess exists but not formalized

Mitigation Coverage Matrix

ThreatPrimary MitigationsStatusNotes
T1: Malicious publication2FA, token scoping, audit logsImplemented2FA optional for login
T2: TyposquattingLevenshtein check, community reportsPartialDetection is alert-only
T3: Package tamperingSignatures, checksumsImplementedStrong coverage
T4: Account takeover2FA, OAuth, leaked password check, rate limitingImplemented2FA optional for login
T5: Documentation attacksOrigin separation, CSP, sandboxingImplementedStrong coverage
T6: Registry compromiseAccess control, monitoringImplementedStrong coverage
T7: DoSRate limiting, CDNImplementedStrong coverage
T8: Vulnerable dependenciesOSV ingestion, advisory CLI reporting, dependency policies, CNAPartialAdvisory consumption and policy enforcement in Hex (Elixir/Mix); not yet in Rebar3 or Gleam
T9: Unmaintained packagesMetadata, retirement statusPartialSuccession process informal
T10: Build pipeline compromise(Planned: Trusted Publishing)PlannedGap - highest priority