tsnet: enable node registration via federated identity
Updates: tailscale.com/corp#34148 Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
This commit is contained in:
committed by
Gesa Stupperich
parent
957a443b23
commit
536188c1b5
@@ -33,54 +33,22 @@ func init() {
|
||||
// false. The "baseURL" defaults to https://api.tailscale.com.
|
||||
// The passed in tags are required, and must be non-empty. These will be
|
||||
// set on the authkey generated by the OAuth2 dance.
|
||||
func resolveAuthKey(ctx context.Context, v string, tags []string) (string, error) {
|
||||
if !strings.HasPrefix(v, "tskey-client-") {
|
||||
return v, nil
|
||||
func resolveAuthKey(ctx context.Context, clientSecret string, tags []string) (string, error) {
|
||||
if !strings.HasPrefix(clientSecret, "tskey-client-") {
|
||||
return clientSecret, nil
|
||||
}
|
||||
if len(tags) == 0 {
|
||||
return "", errors.New("oauth authkeys require --advertise-tags")
|
||||
}
|
||||
|
||||
clientSecret, named, _ := strings.Cut(v, "?")
|
||||
attrs, err := url.ParseQuery(named)
|
||||
strippedSecret, ephemeral, preauth, baseURL, err := parseOptionalAttributes(clientSecret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for k := range attrs {
|
||||
switch k {
|
||||
case "ephemeral", "preauthorized", "baseURL":
|
||||
default:
|
||||
return "", fmt.Errorf("unknown attribute %q", k)
|
||||
}
|
||||
}
|
||||
getBool := func(name string, def bool) (bool, error) {
|
||||
v := attrs.Get(name)
|
||||
if v == "" {
|
||||
return def, nil
|
||||
}
|
||||
ret, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("invalid attribute boolean attribute %s value %q", name, v)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
ephemeral, err := getBool("ephemeral", true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
preauth, err := getBool("preauthorized", false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
baseURL := "https://api.tailscale.com"
|
||||
if v := attrs.Get("baseURL"); v != "" {
|
||||
baseURL = v
|
||||
}
|
||||
|
||||
credentials := clientcredentials.Config{
|
||||
ClientID: "some-client-id", // ignored
|
||||
ClientSecret: clientSecret,
|
||||
ClientSecret: strippedSecret,
|
||||
TokenURL: baseURL + "/api/v2/oauth/token",
|
||||
}
|
||||
|
||||
@@ -106,3 +74,42 @@ func resolveAuthKey(ctx context.Context, v string, tags []string) (string, error
|
||||
}
|
||||
return authkey, nil
|
||||
}
|
||||
|
||||
func parseOptionalAttributes(clientSecret string) (strippedSecret string, ephemeral bool, preauth bool, baseURL string, err error) {
|
||||
strippedSecret, named, _ := strings.Cut(clientSecret, "?")
|
||||
attrs, err := url.ParseQuery(named)
|
||||
if err != nil {
|
||||
return "", false, false, "", err
|
||||
}
|
||||
for k := range attrs {
|
||||
switch k {
|
||||
case "ephemeral", "preauthorized", "baseURL":
|
||||
default:
|
||||
return "", false, false, "", fmt.Errorf("unknown attribute %q", k)
|
||||
}
|
||||
}
|
||||
getBool := func(name string, def bool) (bool, error) {
|
||||
v := attrs.Get(name)
|
||||
if v == "" {
|
||||
return def, nil
|
||||
}
|
||||
ret, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("invalid attribute boolean attribute %s value %q", name, v)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
ephemeral, err = getBool("ephemeral", true)
|
||||
if err != nil {
|
||||
return "", false, false, "", err
|
||||
}
|
||||
preauth, err = getBool("preauthorized", false)
|
||||
if err != nil {
|
||||
return "", false, false, "", err
|
||||
}
|
||||
baseURL = "https://api.tailscale.com"
|
||||
if v := attrs.Get("baseURL"); v != "" {
|
||||
baseURL = v
|
||||
}
|
||||
return strippedSecret, ephemeral, preauth, baseURL, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user