mirror of
https://github.com/tailscale/tailscale.git
synced 2026-02-07 14:32:32 -05:00
This allows fetching auth keys, OAuth client secrets, and ID tokens (for
workload identity federation) from AWS Parameter Store by passing an ARN
as the value. This is a relatively low-overhead mechanism for fetching
these values from an external secret store without needing to run a
secret service.
Usage examples:
# Auth key
tailscale up \
--auth-key=arn:aws:ssm:us-east-1:123456789012:parameter/tailscale/auth-key
# OAuth client secret
tailscale up \
--client-secret=arn:aws:ssm:us-east-1:123456789012:parameter/tailscale/oauth-secret \
--advertise-tags=tag:server
# ID token (for workload identity federation)
tailscale up \
--client-id=my-client \
--id-token=arn:aws:ssm:us-east-1:123456789012:parameter/tailscale/id-token \
--advertise-tags=tag:server
Updates tailscale/corp#28792
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
84 lines
1.9 KiB
Go
84 lines
1.9 KiB
Go
// Copyright (c) Tailscale Inc & contributors
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
//go:build !ts_omit_aws
|
|
|
|
package awsparamstore
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestParseARN(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
wantOk bool
|
|
wantRegion string
|
|
wantParamName string
|
|
}{
|
|
{
|
|
name: "non-arn-passthrough",
|
|
input: "tskey-abcd1234",
|
|
wantOk: false,
|
|
},
|
|
{
|
|
name: "file-prefix-passthrough",
|
|
input: "file:/path/to/key",
|
|
wantOk: false,
|
|
},
|
|
{
|
|
name: "empty-passthrough",
|
|
input: "",
|
|
wantOk: false,
|
|
},
|
|
{
|
|
name: "non-ssm-arn-passthrough",
|
|
input: "arn:aws:s3:::my-bucket",
|
|
wantOk: false,
|
|
},
|
|
{
|
|
name: "invalid-arn-passthrough",
|
|
input: "arn:invalid",
|
|
wantOk: false,
|
|
},
|
|
{
|
|
name: "arn-invalid-resource-passthrough",
|
|
input: "arn:aws:ssm:us-east-1:123456789012:document/myDoc",
|
|
wantOk: false,
|
|
},
|
|
{
|
|
name: "valid-arn",
|
|
input: "arn:aws:ssm:us-west-2:123456789012:parameter/my-secret",
|
|
wantOk: true,
|
|
wantRegion: "us-west-2",
|
|
wantParamName: "/my-secret",
|
|
},
|
|
{
|
|
name: "valid-arn-with-path",
|
|
input: "arn:aws:ssm:eu-central-1:123456789012:parameter/path/to/secret",
|
|
wantOk: true,
|
|
wantRegion: "eu-central-1",
|
|
wantParamName: "/path/to/secret",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
gotRegion, gotParamName, gotOk := parseARN(tt.input)
|
|
if gotOk != tt.wantOk {
|
|
t.Errorf("parseARN(%q) got ok=%v, want %v", tt.input, gotOk, tt.wantOk)
|
|
}
|
|
if !tt.wantOk {
|
|
return
|
|
}
|
|
if gotRegion != tt.wantRegion {
|
|
t.Errorf("parseARN(%q) got region=%q, want %q", tt.input, gotRegion, tt.wantRegion)
|
|
}
|
|
if gotParamName != tt.wantParamName {
|
|
t.Errorf("parseARN(%q) got paramName=%q, want %q", tt.input, gotParamName, tt.wantParamName)
|
|
}
|
|
})
|
|
}
|
|
}
|