Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libs/go/sia/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ func registerSvc(svc sc.Service, ztsUrl string, opts *sc.Options) error {
SpiffeTrustDomain: opts.SpiffeTrustDomain,
SpiffeNamespace: opts.SpiffeNamespace,
AddlSanDNSEntries: opts.AddlSanDNSEntries,
EmailAddresses: opts.EmailAddresses,
ZtsDomains: opts.ZTSCloudDomains,
WildCardDnsName: opts.SanDnsWildcard,
InstanceIdSanDNS: opts.InstanceIdSanDNS,
Expand Down Expand Up @@ -463,6 +464,7 @@ func refreshSvc(svc sc.Service, ztsUrl string, opts *sc.Options) error {
SpiffeTrustDomain: opts.SpiffeTrustDomain,
SpiffeNamespace: opts.SpiffeNamespace,
AddlSanDNSEntries: opts.AddlSanDNSEntries,
EmailAddresses: opts.EmailAddresses,
ZtsDomains: opts.ZTSCloudDomains,
WildCardDnsName: opts.SanDnsWildcard,
InstanceIdSanDNS: opts.InstanceIdSanDNS,
Expand Down
61 changes: 61 additions & 0 deletions libs/go/sia/agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,47 @@ func TestRegisterInstance(test *testing.T) {
}
}

func TestRegisterInstanceWithEmailAddresses(test *testing.T) {

siaDir := test.TempDir()

certFile := fmt.Sprintf("%s/athenz.hockey.cert.pem", siaDir)
caCertFile := fmt.Sprintf("%s/ca.cert.pem", siaDir)

tp := TestProvider{
Name: "athenz.aws.us-west-2",
}
opts := &sc.Options{
Domain: "athenz",
Services: []sc.Service{
{
Name: "hockey",
Uid: util.ExecIdCommand("-u"),
Gid: util.ExecIdCommand("-g"),
},
},
KeyDir: siaDir,
CertDir: siaDir,
AthenzCACertFile: caCertFile,
ZTSCloudDomains: []string{"zts-aws-cloud"},
Region: "us-west-2",
InstanceId: "pod-1234",
Provider: tp,
SanDnsHostname: true,
EmailAddresses: []string{"athenz.hockey@athenz.io", "admin@athenz.io"},
}

err := RegisterInstance("http://127.0.0.1:5084/zts/v1", opts, false)
assert.Nil(test, err, "unable to register instance")

certPem, err := os.ReadFile(certFile)
assert.Nil(test, err, "unable to read x509 certificate file")

cert, err := util.ParseCertificate(string(certPem))
assert.Nil(test, err, "unable to parse x509 certificate")
assert.Equal(test, []string{"athenz.hockey@athenz.io", "admin@athenz.io"}, cert.EmailAddresses)
}

func copyFile(src, dst string) error {
data, err := os.ReadFile(src)
if err != nil {
Expand Down Expand Up @@ -319,6 +360,26 @@ func TestRefreshInstance(test *testing.T) {
}
}

func TestRefreshInstanceWithEmailAddresses(test *testing.T) {

opts, certFile := refreshServiceCertSetup(test)
if opts == nil {
test.Errorf("Certificate setup was not completed successfully")
return
}
opts.EmailAddresses = []string{"athenz.hockey@athenz.io", "admin@athenz.io"}

err := RefreshInstance("http://127.0.0.1:5084/zts/v1", opts)
assert.Nil(test, err, fmt.Sprintf("unable to refresh instance: %v", err))

certPem, err := os.ReadFile(certFile)
assert.Nil(test, err, "unable to read x509 certificate file")

cert, err := util.ParseCertificate(string(certPem))
assert.Nil(test, err, "unable to parse x509 certificate")
assert.Equal(test, []string{"athenz.hockey@athenz.io", "admin@athenz.io"}, cert.EmailAddresses)
}

func TestRoleCertificateRequest(test *testing.T) {

siaDir := test.TempDir()
Expand Down
3 changes: 2 additions & 1 deletion libs/go/sia/aws/options/data/sia_config
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
}
],
"ssh_principals": "host1.athenz.io,host2.athenz.io",
"sandns_x509_cnames": "svc1.athenz.io,svc2.athenz.io"
"sandns_x509_cnames": "svc1.athenz.io,svc2.athenz.io",
"san_email_addresses": "athenz.api@athenz.io,admin@athenz.io"
}
9 changes: 9 additions & 0 deletions libs/go/sia/aws/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ func InitEnvConfig(config *sc.Config) (*sc.Config, *sc.ConfigAccount, error) {
if config.SanDnsX509Cnames == "" {
config.SanDnsX509Cnames = os.Getenv("ATHENZ_SIA_SANDNS_X509_CNAMES")
}
if config.SanEmailAddresses == "" {
config.SanEmailAddresses = os.Getenv("ATHENZ_SIA_SAN_EMAIL_ADDRESSES")
}
if config.HostnameSuffix == "" {
config.HostnameSuffix = os.Getenv("ATHENZ_SIA_HOSTNAME_SUFFIX")
}
Expand Down Expand Up @@ -419,6 +422,7 @@ func setOptions(config *sc.Config, account *sc.ConfigAccount, profileConfig *sc.
runAfterTokensErr := ""
spiffeTrustDomain := ""
addlSanDNSEntries := make([]string, 0)
emailAddresses := make([]string, 0)
runAfterFailExit := false
roleCertsRequired := false
httpPort := 0
Expand Down Expand Up @@ -503,6 +507,10 @@ func setOptions(config *sc.Config, account *sc.ConfigAccount, profileConfig *sc.
sanDSNSEntries := strings.Split(config.SanDnsX509Cnames, ",")
addlSanDNSEntries = append(addlSanDNSEntries, sanDSNSEntries...)
}
if config.SanEmailAddresses != "" {
sanEmailEntries := strings.Split(config.SanEmailAddresses, ",")
emailAddresses = append(emailAddresses, sanEmailEntries...)
}
//update generate role and rotate key options if config is provided
generateRoleKey = config.GenerateRoleKey
rotateKey = config.RotateKey
Expand Down Expand Up @@ -700,6 +708,7 @@ func setOptions(config *sc.Config, account *sc.ConfigAccount, profileConfig *sc.
OmitDomain: account.OmitDomain,
StoreTokenOption: storeTokenOption,
AddlSanDNSEntries: addlSanDNSEntries,
EmailAddresses: emailAddresses,
RunAfterFailExit: runAfterFailExit,
RoleCertsRequired: roleCertsRequired,
OTel: oTelCfg,
Expand Down
4 changes: 4 additions & 0 deletions libs/go/sia/aws/options/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ func TestOptionsWithProfileConfig(t *testing.T) {
assert.Equal(t, 2, len(opts.AddlSanDNSEntries))
assert.Equal(t, "svc1.athenz.io", opts.AddlSanDNSEntries[0])
assert.Equal(t, "svc2.athenz.io", opts.AddlSanDNSEntries[1])

assert.Equal(t, []string{"athenz.api@athenz.io", "admin@athenz.io"}, opts.EmailAddresses)
}

// TestOptionsWithProfileConfigAndProfileTag test the scenario when profile config file is present anbd has profile tag key
Expand Down Expand Up @@ -729,6 +731,7 @@ func TestInitEnvConfig(t *testing.T) {
os.Setenv("ATHENZ_SIA_STORE_TOKEN_OPTION", "2")
os.Setenv("ATHENZ_SIA_OMIT_DOMAIN", "true")
os.Setenv("ATHENZ_SIA_SANDNS_X509_CNAMES", "svc1.athenz.io,svc2.athenz.io")
os.Setenv("ATHENZ_SIA_SAN_EMAIL_ADDRESSES", "athenz.api@athenz.io,admin@athenz.io")
os.Setenv("ATHENZ_SIA_RUN_AFTER", "/run-after.sh")
os.Setenv("ATHENZ_SIA_RUN_AFTER_CERTS_ERROR", "/run-after-error.sh")
os.Setenv("ATHENZ_SIA_RUN_AFTER_TOKENS", "/run-after-tokens.sh")
Expand Down Expand Up @@ -760,6 +763,7 @@ func TestInitEnvConfig(t *testing.T) {
assert.Equal(t, "zts.athenz.cloud", cfg.HostnameSuffix)
assert.Equal(t, "athenz.io", cfg.SpiffeTrustDomain)
assert.Equal(t, "svc1.athenz.io,svc2.athenz.io", cfg.SanDnsX509Cnames)
assert.Equal(t, "athenz.api@athenz.io,admin@athenz.io", cfg.SanEmailAddresses)

assert.Equal(t, 1, len(cfg.AccessTokens))
assert.Equal(t, cfg.AccessTokens["sports/api"].Service, "")
Expand Down
2 changes: 2 additions & 0 deletions libs/go/sia/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ type Config struct {
SanDnsWildcard bool `json:"sandns_wildcard,omitempty"` //san dns wildcard support
SanDnsHostname bool `json:"sandns_hostname,omitempty"` //san dns hostname support
SanDnsX509Cnames string `json:"sandns_x509_cnames,omitempty"` //additional san dns entries to be added to the CSR
SanEmailAddresses string `json:"san_email_addresses,omitempty"` //comma separated list of email addresses to be added to the CSR
UseRegionalSTS bool `json:"regionalsts,omitempty"` //whether to use a regional STS endpoint (default is false)
Account string `json:"aws_account,omitempty"` //name of the AWS account for the identity ( only applicable in AWS environment )
Accounts []ConfigAccount `json:"accounts,omitempty"` //array of configured accounts ( kept for backward compatibility sake )
Expand Down Expand Up @@ -218,6 +219,7 @@ type Options struct {
AccessManagement bool //access management support
ZTSCloudDomains []string //list of domain prefixes for sanDNS entries
AddlSanDNSEntries []string //additional san dns entries to be added to the CSR
EmailAddresses []string //email addresses to be added to the CSR as san email entries
FailCountForExit int //number of failed counts before exiting program
RunAfterCertsOkParts []string //run after certificate parsed parts for success
RunAfterCertsErrParts []string //run after certificate parsed parts for errors
Expand Down
1 change: 1 addition & 0 deletions libs/go/sia/options/data/sia_config
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
],
"ssh_principals": "host1.athenz.io,host2.athenz.io",
"sandns_x509_cnames": "svc1.athenz.io,svc2.athenz.io",
"san_email_addresses": "athenz.api@athenz.io,admin@athenz.io",
"otel": {
"collector_endpoint": "otel-collector.svc.cluster.local:4318",
"mtls": true,
Expand Down
9 changes: 9 additions & 0 deletions libs/go/sia/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ func InitEnvConfig(config *sc.Config, provider provider.Provider) (*sc.Config, *
if config.SanDnsX509Cnames == "" {
config.SanDnsX509Cnames = os.Getenv("ATHENZ_SIA_SANDNS_X509_CNAMES")
}
if config.SanEmailAddresses == "" {
config.SanEmailAddresses = os.Getenv("ATHENZ_SIA_SAN_EMAIL_ADDRESSES")
}
if config.HostnameSuffix == "" {
config.HostnameSuffix = os.Getenv("ATHENZ_SIA_HOSTNAME_SUFFIX")
}
Expand Down Expand Up @@ -460,6 +463,7 @@ func setOptions(config *sc.Config, account *sc.ConfigAccount, profileConfig *sc.
runAfterTokensErr := ""
spiffeTrustDomain := ""
addlSanDNSEntries := make([]string, 0)
emailAddresses := make([]string, 0)
runAfterFailExit := false
roleCertsRequired := false
httpPort := 0
Expand Down Expand Up @@ -534,6 +538,10 @@ func setOptions(config *sc.Config, account *sc.ConfigAccount, profileConfig *sc.
sanDSNSEntries := strings.Split(config.SanDnsX509Cnames, ",")
addlSanDNSEntries = append(addlSanDNSEntries, sanDSNSEntries...)
}
if config.SanEmailAddresses != "" {
sanEmailEntries := strings.Split(config.SanEmailAddresses, ",")
emailAddresses = append(emailAddresses, sanEmailEntries...)
}
//update generate role and rotate key options if config is provided
generateRoleKey = config.GenerateRoleKey
rotateKey = config.RotateKey
Expand Down Expand Up @@ -738,6 +746,7 @@ func setOptions(config *sc.Config, account *sc.ConfigAccount, profileConfig *sc.
OmitDomain: account.OmitDomain,
StoreTokenOption: storeTokenOption,
AddlSanDNSEntries: addlSanDNSEntries,
EmailAddresses: emailAddresses,
RunAfterFailExit: runAfterFailExit,
RoleCertsRequired: roleCertsRequired,
OTel: oTelCfg,
Expand Down
6 changes: 6 additions & 0 deletions libs/go/sia/options/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ func TestOptionsWithConfig(t *testing.T) {
assert.Equal(t, "svc1.athenz.io", opts.AddlSanDNSEntries[0])
assert.Equal(t, "svc2.athenz.io", opts.AddlSanDNSEntries[1])

assert.Equal(t, []string{"athenz.api@athenz.io", "admin@athenz.io"}, opts.EmailAddresses)

// Make sure services are set
assert.Equal(t, 3, len(opts.Services))
assert.Equal(t, "athenz", opts.Domain)
Expand Down Expand Up @@ -711,6 +713,7 @@ func TestInitEnvConfigAwsProvider(t *testing.T) {
os.Setenv("ATHENZ_SIA_STORE_TOKEN_OPTION", "2")
os.Setenv("ATHENZ_SIA_OMIT_DOMAIN", "true")
os.Setenv("ATHENZ_SIA_SANDNS_X509_CNAMES", "svc1.athenz.io,svc2.athenz.io")
os.Setenv("ATHENZ_SIA_SAN_EMAIL_ADDRESSES", "athenz.api@athenz.io,admin@athenz.io")
os.Setenv("ATHENZ_SIA_RUN_AFTER", "/run-after.sh")
os.Setenv("ATHENZ_SIA_RUN_AFTER_CERTS_ERROR", "/run-after-error.sh")
os.Setenv("ATHENZ_SIA_RUN_AFTER_TOKENS", "/run-after-tokens.sh")
Expand Down Expand Up @@ -745,6 +748,7 @@ func TestInitEnvConfigAwsProvider(t *testing.T) {
assert.Equal(t, "zts.athenz.cloud", cfg.HostnameSuffix)
assert.Equal(t, "athenz.io", cfg.SpiffeTrustDomain)
assert.Equal(t, "svc1.athenz.io,svc2.athenz.io", cfg.SanDnsX509Cnames)
assert.Equal(t, "athenz.api@athenz.io,admin@athenz.io", cfg.SanEmailAddresses)

assert.Equal(t, 1, len(cfg.AccessTokens))
assert.Equal(t, cfg.AccessTokens["sports/api"].Service, "")
Expand Down Expand Up @@ -800,6 +804,7 @@ func TestInitEnvConfigGcpProvider(t *testing.T) {
os.Setenv("ATHENZ_SIA_STORE_TOKEN_OPTION", "2")
os.Setenv("ATHENZ_SIA_OMIT_DOMAIN", "true")
os.Setenv("ATHENZ_SIA_SANDNS_X509_CNAMES", "svc1.athenz.io,svc2.athenz.io")
os.Setenv("ATHENZ_SIA_SAN_EMAIL_ADDRESSES", "athenz.api@athenz.io,admin@athenz.io")
os.Setenv("ATHENZ_SIA_DOMAIN_NAME", "athenz")
os.Setenv("ATHENZ_SIA_SERVICE_NAME", "api")
os.Setenv("OTEL_COLLECTOR_ENDPOINT", "otel-collector.svc.cluster.local:4318")
Expand Down Expand Up @@ -833,6 +838,7 @@ func TestInitEnvConfigGcpProvider(t *testing.T) {
assert.Equal(t, "zts.athenz.cloud", cfg.HostnameSuffix)
assert.Equal(t, "athenz.io", cfg.SpiffeTrustDomain)
assert.Equal(t, "svc1.athenz.io,svc2.athenz.io", cfg.SanDnsX509Cnames)
assert.Equal(t, "athenz.api@athenz.io,admin@athenz.io", cfg.SanEmailAddresses)

assert.Equal(t, 1, len(cfg.AccessTokens))
assert.Equal(t, cfg.AccessTokens["sports/api"].Service, "")
Expand Down
21 changes: 21 additions & 0 deletions libs/go/sia/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type SvcCertReqOptions struct {
SpiffeTrustDomain string
SpiffeNamespace string
AddlSanDNSEntries []string
EmailAddresses []string
ZtsDomains []string
IpList []string
WildCardDnsName bool
Expand Down Expand Up @@ -365,6 +366,14 @@ func GenerateSvcCertCSR(key *rsa.PrivateKey, options *SvcCertReqOptions) (string
csrDetails.URIs = AppendUri(csrDetails.URIs, instanceNameUri)
}

// include any email addresses requested by the caller
if len(options.EmailAddresses) > 0 {
csrDetails.EmailList = []string{}
for _, email := range options.EmailAddresses {
csrDetails.EmailList = AppendEmail(csrDetails.EmailList, email)
}
}

csrDetails.IpList = options.IpList
return GenerateX509CSR(key, csrDetails)
}
Expand Down Expand Up @@ -515,6 +524,18 @@ func AppendHostname(hostList []string, hostname string) []string {
return append(hostList, hostname)
}

func AppendEmail(emailList []string, emailAddress string) []string {
if emailAddress == "" {
return emailList
}
for _, email := range emailList {
if email == emailAddress {
return emailList
}
}
return append(emailList, emailAddress)
}
Comment thread
Copilot marked this conversation as resolved.

func GetRoleCertFileName(certDir, fileName, roleName string) string {
switch {
case fileName == "":
Expand Down
Loading
Loading