GitHub Actions - Mic92/niks3 GitHub Wiki

Using niks3 with GitHub Actions

This guide shows how to push Nix build outputs to niks3 from GitHub Actions using OIDC authentication.

Server Setup

Configure your niks3 server to accept GitHub Actions OIDC tokens. See OIDC for general configuration.

GitHub Actions provider example:

{
  services.niks3.oidc.providers.github = {
    issuer = "https://token.actions.githubusercontent.com";
    audience = "https://niks3.example.com";
    boundClaims = {
      repository_owner = [ "your-org" ];
    };
  };
}

Workflow

name: Nix Build

on:
  push:
    branches: [main]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write  # Required for OIDC

    steps:
      - uses: actions/checkout@v4

      - uses: cachix/install-nix-action@v31
        with:
          extra_nix_config: |
            extra-substituters = https://cache.example.com
            extra-trusted-public-keys = my-cache-1:base64encodedpublickey...

      - name: Get OIDC token
        id: oidc
        run: |
          token=$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
            "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://niks3.example.com" | jq -r '.value')
          echo "::add-mask::$token"
          echo "token=$token" >> "$GITHUB_OUTPUT"

      - name: Build
        run: nix build --log-format bar-with-logs

      - name: Push to cache
        run: |
          curl -fsSL "https://github.com/Mic92/niks3/releases/latest/download/niks3_$(uname -s)_$(uname -m).tar.gz" | tar -xzf -
          ./niks3 push \
            --server-url https://niks3.example.com \
            --auth-token "${{ steps.oidc.outputs.token }}" \
            ./result

Key Points

  • id-token: write permission is required for OIDC
  • The audience parameter must match the server configuration
  • The token is masked with ::add-mask:: for security

GitHub Actions Claims

Use these claims for access control in boundClaims:

Claim Example Description
repository octo-org/octo-repo Full repository name
repository_owner octo-org Organization or user
ref refs/heads/main Git ref that triggered the workflow
job_workflow_ref octo-org/octo-repo/.github/workflows/build.yml@refs/heads/main Workflow file

Example restricting to main branch:

{
  services.niks3.oidc.providers.github = {
    issuer = "https://token.actions.githubusercontent.com";
    audience = "https://niks3.example.com";
    boundClaims = {
      repository_owner = [ "your-org" ];
      ref = [ "refs/heads/main" ];
    };
  };
}

Alternative: Using Nix

Instead of downloading the binary:

      - name: Push to cache
        run: |
          nix build -o niks3 github:Mic92/niks3
          niks3/bin/niks3 push \
            --server-url https://niks3.example.com \
            --auth-token "${{ steps.oidc.outputs.token }}" \
            ./result ./niks3

This also pushes niks3 itself to the cache, which can speed up future runs.

Real-World Example