Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions charts/ncps/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,24 @@ data:
allow-delete-verb: true
{{- end }}

{{- if .Values.config.oidc.policies }}
oidc:
policies:
{{- range .Values.config.oidc.policies }}
- issuer: {{ .issuer | quote }}
audience: {{ .audience | quote }}
{{- if .claims }}
claims:
{{- range $key, $values := .claims }}
{{ $key }}:
{{- range $values }}
- {{ . | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

sign-narinfo: {{ ne .Values.config.signing.enabled false }}

upstream:
Expand Down
66 changes: 66 additions & 0 deletions charts/ncps/tests/configmap_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,69 @@ tests:
- matchRegex:
path: data["config.yaml"]
pattern: 'allow-degraded-mode: true'

- it: should not render OIDC section when no policies configured
set:
config.hostname: test.example.com
config.oidc.policies: []
asserts:
- notMatchRegex:
path: data["config.yaml"]
pattern: 'oidc:'

- it: should render OIDC section with single provider
set:
config.hostname: test.example.com
config.oidc.policies:
- issuer: "https://token.actions.githubusercontent.com"
audience: "ncps.example.com"
asserts:
- matchRegex:
path: data["config.yaml"]
pattern: 'oidc:'
- matchRegex:
path: data["config.yaml"]
pattern: 'issuer: "https://token.actions.githubusercontent.com"'
- matchRegex:
path: data["config.yaml"]
pattern: 'audience: "ncps.example.com"'

- it: should render OIDC section with multiple policies and claims
set:
config.hostname: test.example.com
config.oidc.policies:
- issuer: "https://token.actions.githubusercontent.com"
audience: "ncps.example.com"
claims:
sub:
- "repo:myorg/*"
ref:
- "refs/heads/main"
- "refs/tags/*"
- issuer: "https://gitlab.example.com"
audience: "ncps.internal"
asserts:
- matchRegex:
path: data["config.yaml"]
pattern: 'issuer: "https://token.actions.githubusercontent.com"'
- matchRegex:
path: data["config.yaml"]
pattern: 'issuer: "https://gitlab.example.com"'
- matchRegex:
path: data["config.yaml"]
pattern: 'claims:'
- matchRegex:
path: data["config.yaml"]
pattern: 'sub:'
- matchRegex:
path: data["config.yaml"]
pattern: '- "repo:myorg/\*"'
- matchRegex:
path: data["config.yaml"]
pattern: 'ref:'
- matchRegex:
path: data["config.yaml"]
pattern: '- "refs/heads/main"'
- matchRegex:
path: data["config.yaml"]
pattern: '- "refs/tags/\*"'
23 changes: 23 additions & 0 deletions charts/ncps/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,29 @@ config:
# Allow DELETE verb to delete narInfo and nar files
allowDelete: false

# OIDC push authorization (optional)
# When configured, PUT and DELETE requests require a valid OIDC Bearer token.
# Useful for securing push access from CI/CD systems (GitHub Actions, GitLab CI).
# If not configured, existing behavior is preserved.
#
# Each provider requires an issuer (for OIDC discovery) and audience (must
# match the token's aud claim). The optional claims field restricts access
# based on token claim values using glob patterns (* matches any characters).
# Within a claim key, values are ORed. Across claim keys, conditions are ANDed.
oidc:
policies: []
# Example:
# - issuer: "https://token.actions.githubusercontent.com"
# audience: "ncps.example.com"
# claims:
# sub:
# - "repo:myorg/*"
# ref:
# - "refs/heads/main"
# - "refs/tags/*"
# - issuer: "https://gitlab.example.com"
# audience: "ncps.internal"

# NAR info signing
signing:
# Whether to sign narInfo files
Expand Down
22 changes: 22 additions & 0 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@ cache:
allow-delete-verb: true
# Whether to allow the PUT verb to push narInfo and nar files directly
allow-put-verb: true
# OIDC push authorization (optional)
# When configured, PUT and DELETE requests require a valid OIDC Bearer token.
# Useful for securing push access from CI/CD systems (GitHub Actions, GitLab CI)
# that support native OIDC tokens - no stored secrets needed.
# If not configured, existing behavior is preserved (no token required).
#
# Each provider requires an issuer (for OIDC discovery) and audience (must
# match the token's aud claim). The optional claims field restricts access
# based on token claim values using glob patterns (* matches any characters).
# Within a claim key, values are ORed. Across claim keys, conditions are ANDed.
# oidc:
# policies:
# - issuer: "https://token.actions.githubusercontent.com"
# audience: "ncps.mycompany.tld"
# claims:
# sub:
# - "repo:myorg/*"
# ref:
# - "refs/heads/main"
# - "refs/tags/*"
# - issuer: "https://gitlab.internal.company.com"
# audience: "ncps.internal"
# The hostname of the cache server
hostname: "ncps.mycompany.tld"
# Download configuration
Expand Down
1 change: 1 addition & 0 deletions docs/docs/User Guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Welcome to the comprehensive documentation for ncps (Nix Cache Proxy Server). Th
**Features**

- [Content-Defined Chunking (CDC)](User%20Guide/Features/CDC.md)
- [OIDC Push Authorization](User%20Guide/Features/OIDC%20Push%20Authorization.md)

**Deploy for Production**

Expand Down
29 changes: 29 additions & 0 deletions docs/docs/User Guide/Configuration/Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,34 @@ ncps serve \
--netrc-file=/etc/ncps/netrc
```

## OIDC Push Authorization

OIDC token validation for securing PUT and DELETE requests. Configured in the config file only (not via CLI flags). If no policies are configured, existing behavior is preserved.

```yaml
cache:
oidc:
policies:
- issuer: "https://token.actions.githubusercontent.com"
audience: "ncps.example.com"
claims:
sub:
- "repo:myorg/*"
```

Each policy requires:

- **`issuer`** — The OIDC provider URL (used for discovery)
- **`audience`** — Must match the token's `aud` claim

Optional:

- **`claims`** — Map of claim names to glob patterns. Within a key, patterns are ORed. Across keys, conditions are ANDed.

Accepts both `Bearer` and `Basic` auth headers (JWT in password field for netrc compatibility).

See <a class="reference-link" href="../Features/OIDC%20Push%20Authorization.md">OIDC Push Authorization</a> for details.

## Upstream Connection Timeouts

Configure timeout values for upstream cache connections. Increase these if experiencing timeout errors with slow or remote upstreams.
Expand Down Expand Up @@ -484,5 +512,6 @@ See [config.example.yaml](https://github.com/kalbasit/ncps/blob/main/config.exam
- <a class="reference-link" href="Storage.md">Storage</a> - Storage backend details
- <a class="reference-link" href="Database.md">Database</a> - Database backend details
- <a class="reference-link" href="Observability.md">Observability</a> - Monitoring and logging
- <a class="reference-link" href="../Features/OIDC%20Push%20Authorization.md">OIDC Push Authorization</a> - Securing push access with OIDC tokens
- <a class="reference-link" href="../Deployment/High%20Availability.md">High Availability</a> - HA configuration
- <a class="reference-link" href="../Deployment/Distributed%20Locking.md">Distributed Locking</a> - Lock tuning
Loading