Replies: 8 comments 6 replies
|
Hi @avidal! I'm Dosu and I’m helping the ncps team. There is currently no native support or documentation for OIDC authorization or oidc.policies in ncps for PUT/DELETE operations. The official configuration only allows you to enable or disable PUT and DELETE verbs globally (for example, with allowPutVerb and allowDeleteVerb), but does not provide built-in mechanisms for fine-grained authorization or OIDC-based access control for these actions. The only authentication-related option mentioned is the use of a netrc file for upstream authentication, which is not tied to OIDC or claim-based policies reference. If you need OIDC-based authorization, your approach of placing an authorization proxy in front of ncps is currently the most practical solution. This proxy would handle OIDC token validation and enforce your desired policies before forwarding requests to ncps, which would be running with PUT/DELETE enabled but not exposed directly. There are no community discussions or documentation about OIDC authorization or similar features in ncps at this time. If you want to gauge community interest, you might consider sharing your use case and proposal in relevant forums or channels. To reply, just mention @dosu. Share context across your team and agents. Try Dosu. |
|
@dosu I'm aware, that's why I filed the discussion. The documentation suggests that if you have ideas or feature suggestions to open a discussion :) |
|
@avidal thanks for opening this discussion, I've also been meaning to figure a way to add authentication but I wanted to leave this for a bit later since it's still pretty early for this. With that said, I want to give your idea a fair assessment but I'm currently trying to solve #660, #805, #806, among others, and prep to release v0.8.5 and v0.9.0... Once I am done, I will get back to you. Expect a reply within the next week or so. |
|
Of course, no worries. I have a branch on my fork that implements it
including tests and documentation but it may be a bit large to ingest in
one review.
Early next week I'll expand this post to explain in more detail the
proposal so it's a bit easier to reason about and discuss.
…-- Alex Vidal
On Fri, Feb 13, 2026, 7:53 PM Wael Nasreddine ***@***.***> wrote:
@avidal <https://github.com/avidal> thanks for opening this discussion,
I've also been meaning to figure a way to add authentication but I wanted
to leave this for a bit later since it's still pretty early for this. With
that said, I want to give your idea a fair assessment but I'm currently
trying to solve #660 <#660>, #805
<#805>, #806
<#806>, among others, and prep to
release v0.8.5 and v0.9.0... Once I am done, I will get back to you. Expect
a reply within the next week or so.
—
Reply to this email directly, view it on GitHub
<#885 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABO3Z5UYO3J664L7YSSYN34LZ5YNAVCNFSM6AAAAACVCFRFEKVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTKOBQGE3TONY>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
Another option for the config that may be simpler to read is to nest So, instead of: You have: |
|
As an aside, I'm currently working on a separate flake that implements OIDC policies as a reverse proxy that I can stand in front of ncps so there's no urgency with this discussion (or the linked PR). Please don't feel the need to take it to satisfy my use case. |
|
@avidal thank you for patiently waiting while I released v0.9 and a few more days to "brain reset --hard"... This is a fantastic proposal. I completely agree with your assessment. Relying on Workload Identity Federation (short-lived, provider-minted tokens) is vastly superior to managing static, long-lived API keys for CI/CD. While my default SRE instinct is often to push authentication to an edge proxy (like OAuth2-proxy), doing deep claim validation (like ensuring pushes only happen from As we move forward with the implementation, here are a few operational edge cases we need to ensure are covered:
Here is a quick example of what that configuration could look like in practice, let me know what you think: oidc:
policies:
# CI Pipeline: Can read and push from the main branch
- issuer: "https://token.actions.githubusercontent.com"
audience: "ncps.mydomain.tld"
methods: ["GET", "HEAD", "PUT"]
claims:
sub:
- "repo:myorg/*"
ref:
- "refs/heads/main"
- "refs/tags/*"
# Local Developers: Can only read (pull) via internal SSO
- issuer: "https://sso.internal.mydomain.tld/application/o/ncps/"
audience: "ncps.mydomain.tld"
methods: ["GET", "HEAD"]
claims:
groups:
- "nix-developers"I see you already have a draft PR open for this (#925). Could you update the PR and resolve any merge conflicts? Once it's ready, please trigger an automated review by commenting |
|
@avidal are you still interested in making this happen? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I'm looking to deploy ncps internally at my company to bootstrap a bottom-up nix adoption. Part of this is that I want CI jobs to build flakes automatically and push them to ncps, but I don't want unauthenticated pushes open in general.
My first thought was to put an authorization proxy in front of ncps to perform these checks and then proxy to ncps (which is running with unauthenticated pushes).
But, maybe this is something the community in general would be in favor of?
There are several ways to add authorization, each with their own pros and cons. Briefly:
Opaque API keys / credentials: Simple to implement and understand, but requires a database or config file to track issued credentials. Expiration is problematic.
Self-minted JWTs: This is what attic does. An admin command can mint a JWT with specific access. Outside of the secret used to generate and sign the JWTs, no state is required on the server. While you can mint a JWT with an expiration, this complicates things: too short an expiration and you have to manually regenerate. Too long and a leaked token can operate with impunity.
OAuth consumer: Much more significant integration. Users have to configure ncps as a consumer in their oauth provider, and configure clients to authenticate. Requires a database to track clients.
OIDC consumer: While full OIDC is about as involved as OAuth, the relevant part here is the "identity token". The sweet spot if your clients can generate an identity token (which every(?) CI provider can issue). Largely stateless on the consumer (assuming they pre-fetch the signing keys). Since each "job" will generate a unique identity token, each token can have a very short expiration.
While I do think that there is value in self-minted JWTs, especially for eg, self-hosters that still want some authorization, I'd like to focus this discussion on OIDC.
OIDC
If you're unfamiliar, OIDC is "OpenID Connect". It's an open-standard authentication "protocol" built on top of OAuth 2.0. Where OAuth focuses on delegated authorization (minting tokens allowing service A to interact with service B on behalf of user U), OIDC is purely focused on identity and is fairly standard in the world of single sign on.
As mentioned above, while full OIDC can be as involved as OAuth, it doesn't have to be. In practical terms, if all you care about is the identity token, it's more correct to call this something like "federated authorization". However, many providers (such as GitHub and Gitlab) call this feature on their end OIDC, so it makes sense to call it OIDC here as well.
This system is designed around the "identity token". An identity token is issued by the provider (eg, your CI system). The identity token is a JWT that contains some data about the environment. For example, a GitHub Actions OIDC token will look similar to (docs):
A workflow can acquire this token by setting
permissions.id-tokens: writeand requesting a token through octokit or curl. See the linked docs for more.Checking tokens
Every OIDC provider publishes a well-known URI that can be appended to the issuer (
issin the token above). In the Actions case, it's at https://token.actions.githubusercontent.com/.well-known/openid-configurationThis document has a
jwks_urithat points to a "JSON Web Key Set" which defines the signing keys that the OIDC provider uses to sign tokens. This is the only state that a consuming service needs to have, and it can be fetched on startup.A consumer of these identity tokens can use the key set to verify inbound tokens and then, provided the token is otherwise valid, match claims in the token against their own predefined policies.
Configuration example
Consider an
oidc.policiesblock in thencpsconfig file. Each policy will list an issuer and an audience at a minimum and optionally a set of claims. Each claim must match. If a claim has multiple possible values, at least one of the values for that claim must match (AND across claims, OR within a claim).Example:
So, with the above config a token from GitHub Actions would be allowed if:
Whereas any token issued by your internal GitLab instance intended for your ncps server (via audience) would be allowed.
All reactions