-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OIDC configure expiry time #1176
Comments
The implementation uses whatever your OIDC provider puts in the exp-field of the issued token. It may indicate that your provider has a default token lifetime of 1hr. |
I just came across this while wondering why my node was getting such a short expiry time or expiring at all for that matter. |
Hhhmmmm that may be a problem then because all my OIDC clients will disconnect once an hour.
I think the same yes. |
Maybe it could be made possible to disable expiring nodes on token expiry for now until the OIDC implementation is complete? See #1067 |
maybe passing a default expiry time by configuration? |
Only the ID token from OIDC is used per right now. Related code and discussions:
Looking forward, there is a couple of obvious things that could be done:
What would be the preferred approach to handling this @kradalby? |
As OIDC tokens tend to be short-lived (with google it's 1h, with others perhaps even shorter), I wonder why machines should follow the same expiry. On the commercial Tailscale server, newly registered machines get a fixed expiration period (default 180 days but can be configured on your tailnet using the admin console) unless they have ACL tags, then key expiry is disabled. |
Exactly. As I mentioned, for Keycloak the default is 5 minutes. It would be the best if
But if the original Tailscale behaviour is 180 days or a different configurable value on registration via OIDC, that would be fine too and I'd assume much easier to implement. But right now due to security concerns with creating such long-lived access tokens (as they could be valid on other services by configuration error for example) the feature is not really usable for me. |
Following @evenh comment, trying to increase the token expiry time in Keycloak - which is what I use for my OIDC provider - it seems to only max out at 10 hours when Headscale updates a client. Which seems really random, so either a bug with Keycloak/OIDC implementation or built-in limitation. Though while the token time is fair in terms of short-lived tokens, some users may need it at max a month without making the OIDC provider insecure. Implementing |
I agree that it's an easy and acceptable stopgap solution. |
I won't have time to tackle the integration tests anytime soon, but could something like this work? From 28d8dd3d32003b826febcc2699c0706f71258b2e Mon Sep 17 00:00:00 2001
From: Even Holthe <[email protected]>
Date: Mon, 30 Jan 2023 16:05:56 +0100
Subject: [PATCH] Add option for overriding OIDC ID Token expiry
Closes #1176
---
config.go | 13 +++++++++++++
oidc.go | 16 ++++++++++++++--
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/config.go b/config.go
index 6865b30..f23e827 100644
--- a/config.go
+++ b/config.go
@@ -101,6 +101,7 @@ type OIDCConfig struct {
AllowedUsers []string
AllowedGroups []string
StripEmaildomain bool
+ OverrideExpiry *time.Duration
}
type DERPConfig struct {
@@ -180,6 +181,7 @@ func LoadConfig(path string, isFile bool) error {
viper.SetDefault("oidc.scope", []string{oidc.ScopeOpenID, "profile", "email"})
viper.SetDefault("oidc.strip_email_domain", true)
viper.SetDefault("oidc.only_start_if_oidc_is_available", true)
+ viper.SetDefault("oidc.override_expiry", "")
viper.SetDefault("logtail.enabled", false)
viper.SetDefault("randomize_client_port", false)
@@ -603,6 +605,17 @@ func GetHeadscaleConfig() (*Config, error) {
AllowedUsers: viper.GetStringSlice("oidc.allowed_users"),
AllowedGroups: viper.GetStringSlice("oidc.allowed_groups"),
StripEmaildomain: viper.GetBool("oidc.strip_email_domain"),
+ OverrideExpiry: func() *time.Duration {
+ // if empty, no override set
+ if e := viper.GetString("oidc.override_expiry"); len(e) == 0 {
+ return nil
+ }
+
+ // return parsed override expiry
+ e := viper.GetDuration("oidc.override_expiry")
+
+ return &e
+ }(),
},
LogTail: logConfig,
diff --git a/oidc.go b/oidc.go
index 4909ba9..4961041 100644
--- a/oidc.go
+++ b/oidc.go
@@ -68,6 +68,17 @@ func (h *Headscale) initOIDC() error {
return nil
}
+func (h *Headscale) determineTokenExpiration(originalExpiration time.Time) time.Time {
+ overriddenExpirationDuration := h.cfg.OIDC.OverrideExpiry
+ // don't modify expiry
+ if overriddenExpirationDuration == nil {
+ return originalExpiration
+ }
+
+ // calculate a new expiry based on override
+ return time.Now().Add(*overriddenExpirationDuration)
+}
+
// RegisterOIDC redirects to the OIDC provider for authentication
// Puts NodeKey in cache so the callback can retrieve it using the oidc state param
// Listens in /oidc/register/:nKey.
@@ -193,6 +204,7 @@ func (h *Headscale) OIDCCallback(
if err != nil {
return
}
+ idTokenExpiry := h.determineTokenExpiration(idToken.Expiry)
// TODO: we can use userinfo at some point to grab additional information about the user (groups membership, etc)
// userInfo, err := oidcProvider.UserInfo(context.Background(), oauth2.StaticTokenSource(oauth2Token))
@@ -218,7 +230,7 @@ func (h *Headscale) OIDCCallback(
return
}
- nodeKey, machineExists, err := h.validateMachineForOIDCCallback(writer, state, claims, idToken.Expiry)
+ nodeKey, machineExists, err := h.validateMachineForOIDCCallback(writer, state, claims, idTokenExpiry)
if err != nil || machineExists {
return
}
@@ -236,7 +248,7 @@ func (h *Headscale) OIDCCallback(
return
}
- if err := h.registerMachineForOIDCCallback(writer, user, nodeKey, idToken.Expiry); err != nil {
+ if err := h.registerMachineForOIDCCallback(writer, user, nodeKey, idTokenExpiry); err != nil {
return
}
--
2.37.5
|
@evenh That patch seems to work! I'll roll with the patched version until it becomes added officially. |
This commit adds a default OpenID Connect expiry to 180d to align with Tailscale SaaS (previously infinite or based on token expiry). In addition, it adds an option use the expiry time from the Token sent by the OpenID provider. This will typically cause really short expiry and you should only turn on this option if you know what you are desiring. This fixes juanfont#1176. Signed-off-by: Kristoffer Dalby <[email protected]>
This commit adds a default OpenID Connect expiry to 180d to align with Tailscale SaaS (previously infinite or based on token expiry). In addition, it adds an option use the expiry time from the Token sent by the OpenID provider. This will typically cause really short expiry and you should only turn on this option if you know what you are desiring. This fixes juanfont#1176. Co-authored-by: Even Holthe <[email protected]> Signed-off-by: Kristoffer Dalby <[email protected]>
I have created #1191 based on @evenh's patch, it takes a slightly different approach: Instead of adding an option to override the new behaviour (using the token expiry) it makes that an optional behaviour for people who desire it. Instead of reverting back to setting no expiry for OpenID clients, it will now align with Tailscale SaaS and set 180 days by default, and of course exposing the option to the user so it can be set longer or short as desired. Please help testing it or voice concerns on the PR. |
This commit adds a default OpenID Connect expiry to 180d to align with Tailscale SaaS (previously infinite or based on token expiry). In addition, it adds an option use the expiry time from the Token sent by the OpenID provider. This will typically cause really short expiry and you should only turn on this option if you know what you are desiring. This fixes juanfont#1176. Co-authored-by: Even Holthe <[email protected]> Signed-off-by: Kristoffer Dalby <[email protected]>
This commit adds a default OpenID Connect expiry to 180d to align with Tailscale SaaS (previously infinite or based on token expiry). In addition, it adds an option use the expiry time from the Token sent by the OpenID provider. This will typically cause really short expiry and you should only turn on this option if you know what you are desiring. This fixes juanfont#1176. Co-authored-by: Even Holthe <[email protected]> Signed-off-by: Kristoffer Dalby <[email protected]>
This commit adds a default OpenID Connect expiry to 180d to align with Tailscale SaaS (previously infinite or based on token expiry). In addition, it adds an option use the expiry time from the Token sent by the OpenID provider. This will typically cause really short expiry and you should only turn on this option if you know what you are desiring. This fixes #1176. Co-authored-by: Even Holthe <[email protected]> Signed-off-by: Kristoffer Dalby <[email protected]>
Hi,
I run Headscale 0.17 and planning to upgrade to 0.18. on my test server running 0.18 I see that the oidc users have a default expiration time of 60 minutes.
how do I configure the expiration time for oidc users to make it longer?
thanks.
The text was updated successfully, but these errors were encountered: