Hex configuration

OSA Proxy supports scanning Hex packages and signed protobuf manifests. During manifest scanning, the service verifies the upstream repository signature, processes package versions, and signs the modified response with its own RSA key.

OSA Proxy configuration

Generate a stable RSA key and keep it in secret storage:

openssl genpkey -algorithm RSA \
  -pkeyopt rsa_keygen_bits:3072 \
  -out osa-hex-signing.pem

Do not generate a new key every time OSA Proxy starts. After a key change, clients that retain the previous public key will reject signed manifests. All OSA Proxy replicas must use the same private key.

Pass the key inline with signing-private-key or provide a PEM file path with signing-private-key-file. For example, to use a secret from Vault:

hex:
  enabled: true
  signing-private-key: ${HEX_SIGNING_PRIVATE_KEY:}
  repository:
    - name: codescoring-hex
      registry: https://repo.hex.pm
      scan-manifest: true
      scan-package: true
      remove-blocked-versions: false
      work-mode: strict_wait

For a mounted file, use:

hex:
  enabled: true
  signing-private-key-file: ${HEX_SIGNING_PRIVATE_KEY_FILE:/run/secrets/osa-hex-signing.pem}

When both parameters are set, signing-private-key takes precedence and the file is not read. One of the two parameters is required when at least one Hex repository has scan-manifest enabled.

You do not need to configure the public key. OSA Proxy derives it at startup and serves it at /{repository-name}/public_key. The service also obtains the upstream repository public key automatically and keeps it in memory only.

Connecting Mix

The following example assumes that the OSA Proxy repository is available at https://osa-proxy.example.com/codescoring-hex.

curl -fsS \
  https://osa-proxy.example.com/codescoring-hex/public_key \
  -o /tmp/osa-hex-public-key.pem

mix hex.repo add osa-proxy \
  https://osa-proxy.example.com/codescoring-hex \
  --public-key /tmp/osa-hex-public-key.pem

mix hex.repo set hexpm \
  --url https://osa-proxy.example.com/codescoring-hex \
  --public-key /tmp/osa-hex-public-key.pem

The mix hex.repo add command creates the local osa-proxy alias that Hex uses to retrieve the dependency policy. The mix hex.repo set command routes requests to the standard hexpm repository through OSA Proxy.

remove-blocked-versions: false mode

By default, remove-blocked-versions: true: OSA Proxy physically removes a blocked release from the protobuf manifest.

With false, the release remains in the manifest and receives the standard Hex retired: security marker. Its message contains the blocking CodeScoring policy name. The retired marker itself only produces a warning and does not prevent Hex from installing the version. To block it during resolution, enable the built-in signed OSA Proxy policy. Hex 2.5 or newer is required.

Enable the policy for one command:

HEX_POLICY=osa-proxy/codescoring \
  mix run --no-mix-exs -e 'Mix.install([:jason], force: true)'

Or persist it in the Hex configuration:

mix hex.config policy osa-proxy/codescoring

In osa-proxy/codescoring:

  • osa-proxy is the local repository name from mix hex.repo add;
  • codescoring is the built-in policy name.

Hex retrieves the policy with GET https://osa-proxy.example.com/codescoring-hex/policies/codescoring. The policy excludes releases retired for security from a new resolution, including releases marked this way by the upstream repository.

Locked versions

The policy does not replace versions already recorded in mix.lock. To test blocking, resolve without the old lock file or use a clean environment. When filtering succeeds, Hex reports that the policy hid the version and selects the next allowed version.

Was this page helpful?