headplane
headplane copied to clipboard
User Permissions
It should limit users' Permissions. currently, everyone who can log in with OIDC can manage all the config.
How would you suggest implementing such a feature? I don't want to deviate from Headscale's permissions, and I'm unaware of a way to limit permissions from Headscale itself.
For administrators, OIDC can ask for another field e.g. groups or roles. use this information to filter.
e.g.
if a user is in admin, then he/she can log in, otherwise reject.
For a normal user, maybe only show his/her own devices? and he/she cannot do anything?
The issue is right now, headscale doesn't support any kind of admin groups and I don't want to diverge from that, I do think it's a really good idea though and that we can take advantage of extra_params in the config.
Not sure if headscale supports them yet (I haven't dug too far), but could you use grants? Alternatively, what about an ACL group?
I mean we could really do an ACL group, ideally I want something with the least amount of friction if/when Headscale adds native support for this.
Headscale has an OIDC allowed_groups and allowed_domains (see: headscale doc on oidc).
headscale doc on oidc
No, there are different things. Everyone who can log in has admin permission in Headplane currently, that is what we want to avoid.
headscale doc on oidc
No, there are different things. Everyone who can log in has admin permission in Headplane currently, that is what we want to avoid.
You are right. I mean Headplane can get these settings from Headscale's config -- although this doesn't seem wise either. It should really be a subset of Headscale users.
The discussion is diverging slightly, but it seems there is another open-source alternative to Tailscale called Ionscale, separate from headscale.
ionscale has a feature called Multi Tailnet, which allows the management of devices, users, ACLs, and other settings within a unit called a Tailnet.
By integrating this solution, users can manage only the devices within their own Tailnet as a Tailnet administrator, preventing interference with other users.
How about use tag or group to determine who will be an admin or not?
You mean as in, use the ACLs file as the way to determine who is able to do what? This is something I'm open to for now, the question is are we just mapping ACL defined usernames directly to OIDC usernames or what?
Or maybe just add a whitelist in the headplane environement config ?
Could also, when using OIDC use 2 Applications with Groups allowing access to login on the OIDC side. I'm using Authentik to do this. One App and Provider for Headscale, and another for headplane With Groups allowing access to them.
@DeadClap this is how I currently do it. But I want users to be able to manage their own devices via headplane
I was thinking of implementing it in Tailscale grants like this:
{
"groups": {
"group:admin": ["tale"]
},
"grants": [
{
// src is important, dest is NOT, but keep it the same
"src": ["group:admin"],
"dst": ["group:admin"],
"app": {
"tale.me/cap/headplane": [{
"dnsManage": true,
"aclManage": true,
"nodeView": "all", // "self", "none"
"nodeRegister": "all", // "self", "none"
"preauthIssue": "all", // "self"
}]
}
}
]
}
Many things to consider here, and I'm not even sure if this is a valid Tailscale grant:
- What should the actual capabilities look like
dnsManageis straightforward but other ones may not be (please drop your ideas below, I'm interested in how you expect this to be)? - How granular should our permissions be, what should be possible and what shouldn't?
- Are grants even the right way to go?
What about true or false style, something like this?
- readOwnMachines
- writeOwnMachines
- readAllMachines
- writeAllMachines
- readUsers
- writeUsers
- readPolicy
- writePolicy
- readNetworkConfig
- writeNetworkConfig
- readPreAuthKeys
- writePreAuthKeys
I was thinking that or a "ACL style" similar to how Kubernetes RBAC policies are defined.
{
"app": {
"tale.me/cap/headplane": [{
"machines": {
"verbs": ["GET", "POST", "PATCH", "DELETE"],
"domains": ["self", "all", "some_wildcard*"]
}
}]
}
}
Could do something like this?
readMachines (none, self, all) writeMachines (none, self, all) readUsers (none, self, all) writeUsers (none, self, all) policy (none, read, write) networkConfig (none, read, write) readPreAuthKeys (none, self, all) writePreAuthKeys (none, self, all)
Writing would imply your ability to read. So you could never write all but only read self. But also policy write would give you policy read.
If you're going down the path of grants, you could also use TS as the method of authentication as well. A bit like tsidp, hello, and nginx-auth all work.
@tale Good evening, I just started using Headplane and it is amazing. I am still getting to grips with it but its great so far. I was wonding if you could use this Authentik Enhancements
As a means to limit users access to certain parts of an app (i.e the Admin page) This might stop all not users but I think it would work.
Hope this helps someone and if anyone works out how to use it please let me know...
Also using Authentik + oidc with headplane, interesting in this further or how to avoid /admin page for non admins
how to avoid /admin page for non admins
I just have two OIDC apps, one for Headscale, one for Headplane that are scoped to two groups of users:
Headscale-Admingets both Headscale and HeadplaneHeadscale-Usergets only Headscale
how to avoid /admin page for non admins
I just have two OIDC apps, one for Headscale, one for Headplane that are scoped to two groups of users:
Headscale-Admingets both Headscale and HeadplaneHeadscale-Usergets only Headscale
But for this you need other config for OIDC than in headscale config?
I mean yes, it’s got its own client id and client secret. But it’s really not that much effort to set up. I think it took me all of 2 minutes from start to finish and it’s never been touched since.
I mean yes, it’s got its own client id and client secret. But it’s really not that much effort to set up. I think it took me all of 2 minutes from start to finish and it’s never been touched since.
Thanks, working fine
As 0.24 changed OIDC things, I'm looking to implement more auth related stuff now and I think as a start I'll do this: https://tailscale.com/kb/1138/user-roles#standard-roles. It makes the most sense and is the easiest to at least make an effort with some level of auth.
I have noticed that only the 1st user who logged in via OIDC is added to headscale. Subsequent users are not. Anyone else with this issue?
Big update on this. Lots of authentication changes are coming in 0.6. https://github.com/tale/headplane/blob/main/app/server/web/roles.ts
All of the roles and their capabilities have been defined, I need to go through and start retroactively checking for permissions in places that need them. The other annoying thing to work through is tying a user to a Headscale user. I'm doing this via the OIDC subject that Headscale will attach to the user API if someone authenticated that way.
Because of the nature of how auth works: Any API key logins are considered admin and can do EVERYTHING except delete the owner user.
Landed in 0.6.0. Going to close this!