Skip to content

Commit

Permalink
Merge pull request #1 from SilvaMatteus/scone_svid_store_plugin_sessi…
Browse files Browse the repository at this point in the history
…on_template

Make the session template configurable
  • Loading branch information
SilvaMatteus authored Mar 1, 2021
2 parents 294f328 + fb110a0 commit f9e6500
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 103 deletions.
10 changes: 10 additions & 0 deletions conf/agent/agent_full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,16 @@ plugins {

# # cas_predecessor_dir:
# # cas_predecessor_dir = ""

# # svid_session_template_file:
# # svid_session_template_file = ""

# # ca_bundle_session_template_file:
# # ca_bundle_session_template_file= ""

# # federated_bundles_session_template_file:
# # federated_bundles_session_template_file = ""

# }
# }

Expand Down
214 changes: 111 additions & 103 deletions pkg/agent/plugin/svidstore/scone/scone.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,30 @@ import (
)

const (
pluginName = "scone_cas_secretsmanager"
casSessionNameSelecType = "cas_session_name"
casSessionHashSelecType = "cas_session_hash"
casSessionEndpoint = "/session"
noPredHashMsg = "No predecessor hash specified albeit session alias used already"
predNotNeededMsg = "Predecessor hash specified albeit session alias unused"
certificatePemType = "CERTIFICATE"
privateKeyPemType = "PRIVATE KEY"
sessionNameSVIDPrefix = "spire-svid-"
sessionNameCA = "spire-ca"
sessionNameFederatedBundles = "spire-federated-bundles"
pluginName = "scone_cas_secretsmanager"
casSessionNameSelecType = "cas_session_name"
casSessionHashSelecType = "cas_session_hash"
casSessionEndpoint = "/session"
noPredHashMsg = "No predecessor hash specified albeit session alias used already"
predNotNeededMsg = "Predecessor hash specified albeit session alias unused"
certificatePemType = "CERTIFICATE"
privateKeyPemType = "PRIVATE KEY"
predecessorPlaceholder = "${predecessor}"
svidPlaceholder = "${svid}"
svidKeyPlaceholder = "${svid-key}"
sessionNameSelectorPlaceholder = "${session-name-selector}"
sessionHashSelectorPlaceholder = "${session-hash-selector}"
caTrustBundlePlaceholder = "${trust-bundle-ca}"
nameYAMLKey = "name:"
)

var (
svidSessionTemplate string
caBundleSessionTemplate string
federatedBundlesSessionTemplate string
sessionNameSVIDPrefix string
sessionNameCA string
sessionNameFederatedBundles string
)

type sconeWorkloadInfo struct {
Expand All @@ -62,10 +75,13 @@ func New() *SecretsManagerPlugin {
}

type Config struct {
CasAddress string `hcl:"cas_address"`
ClientCertDir string `hcl:"cas_client_certificate"`
ClientKeyDir string `hcl:"cas_client_key"`
PredecessorDir string `hcl:"cas_predecessor_dir"`
CasAddress string `hcl:"cas_address"`
ClientCertDir string `hcl:"cas_client_certificate"`
ClientKeyDir string `hcl:"cas_client_key"`
PredecessorDir string `hcl:"cas_predecessor_dir"`
SVIDSessionTemplateFile string `hcl:"svid_session_template_file"`
CABundleSessionTemplateFile string `hcl:"ca_bundle_session_template_file"`
FederatedBundlesSessionTemplateFile string `hcl:"federated_bundles_session_template_file"`
}

type SecretsManagerPlugin struct {
Expand All @@ -87,10 +103,44 @@ func (p *SecretsManagerPlugin) SetLogger(log hclog.Logger) {
func (p *SecretsManagerPlugin) Configure(ctx context.Context, req *spi.ConfigureRequest) (*spi.ConfigureResponse, error) {
// Parse HCL config payload into config struct
config := &Config{}
if err := hcl.Decode(config, req.Configuration); err != nil {
var err error
if err = hcl.Decode(config, req.Configuration); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "unable to decode configuration: %v", err)
}

caSessionTemplateBytes, err := ioutil.ReadFile(config.CABundleSessionTemplateFile)
if err != nil {
return &spi.ConfigureResponse{}, errors.New("error in ca_bundle_session_template_file config. " + err.Error())
}

federatedBundlesSessionTemplateBytes, err := ioutil.ReadFile(config.FederatedBundlesSessionTemplateFile)
if err != nil {
return &spi.ConfigureResponse{}, errors.New("error in federated_bundles_session_template_file config. " + err.Error())
}

svidSessionTemplateBytes, nil := ioutil.ReadFile(config.SVIDSessionTemplateFile)
if err != nil {
return &spi.ConfigureResponse{}, errors.New("error in svid_session_template_file config. " + err.Error())
}

caBundleSessionTemplate = string(caSessionTemplateBytes)
sessionNameCA, err = getSessionNameFromTemplate(caBundleSessionTemplate)
if err != nil {
return &spi.ConfigureResponse{}, err
}

federatedBundlesSessionTemplate = string(federatedBundlesSessionTemplateBytes)
sessionNameFederatedBundles, err = getSessionNameFromTemplate(federatedBundlesSessionTemplate)
if err != nil {
return &spi.ConfigureResponse{}, err
}

svidSessionTemplate = string(svidSessionTemplateBytes)
sessionNameSVIDPrefix, err = getSVIDSessionNameFromTemplate(svidSessionTemplate)
if err != nil {
return &spi.ConfigureResponse{}, err
}

p.mtx.Lock()
defer p.mtx.Unlock()

Expand All @@ -103,6 +153,28 @@ func (*SecretsManagerPlugin) GetPluginInfo(context.Context, *spi.GetPluginInfoRe
return &spi.GetPluginInfoResponse{}, nil
}

func getSVIDSessionNameFromTemplate(template string) (string, error) {
haystack := strings.Split(template, "\n")
for _, item := range haystack {
if strings.HasPrefix(item, nameYAMLKey) {
nameWithPlaceholder := strings.Split(item, nameYAMLKey)[1]
return strings.Trim(
strings.Split(nameWithPlaceholder, sessionNameSelectorPlaceholder)[0], " "), nil
}
}
return "", errors.New("cannot find name prefix in template for SVID session")
}

func getSessionNameFromTemplate(template string) (string, error) {
haystack := strings.Split(template, "\n")
for _, item := range haystack {
if strings.HasPrefix(item, nameYAMLKey) {
return strings.Trim(strings.Split(item, nameYAMLKey)[1], " "), nil
}
}
return "", errors.New("cannot find session name in template")
}

func (p *SecretsManagerPlugin) extractWorkloadInfoFromSelectors(selectors []*common.Selector) (*sconeWorkloadInfo, error) {

hasSconeSessionName, hasSconeSessionHash := false, false
Expand Down Expand Up @@ -132,97 +204,32 @@ func (p *SecretsManagerPlugin) extractWorkloadInfoFromSelectors(selectors []*com

// generateSVIDSessionText is an auxiliar func to gerenate the SCONE CAS session expected text format
func (p *SecretsManagerPlugin) generateSVIDSessionText(sconeWorkloadInfo *sconeWorkloadInfo, svid string, privateKey string) string {
var predecessorLine string
predecessor, err := p.readPredecessor(sessionNameSVIDPrefix + sconeWorkloadInfo.CasSessionName)
if err != nil {
predecessorLine = ""
} else {
predecessorLine = "predecessor: " + predecessor
}

sessionTemplateP1 := "name: " + sessionNameSVIDPrefix + sconeWorkloadInfo.CasSessionName + "\nversion: \"0.3\"\n"
sessionTemplateP2 := `
secrets:
- name: svid
kind: x509
value: |
`
sessionTemplateP3 := `
export:
session: `
sessionTemplateP4 := `
session_hash: `
sessionTemplateP5 := `
private_key: svid_key
- name: svid_key
kind: private-key
export:
session: `
sessionTemplateP6 := `
session_hash: `
sessionTemplateP7 := `
value: |
`
sessionTemplate := sessionTemplateP1 +
predecessorLine +
sessionTemplateP2 +
pemToSconeInjectionFile(svid) +
sessionTemplateP3 +
sconeWorkloadInfo.CasSessionName +
sessionTemplateP4 +
sconeWorkloadInfo.CasSessionHash +
sessionTemplateP5 +
sconeWorkloadInfo.CasSessionName +
sessionTemplateP6 +
sconeWorkloadInfo.CasSessionHash +
sessionTemplateP7 +
pemToSconeInjectionFile(privateKey)

return sessionTemplate
session := strings.ReplaceAll(svidSessionTemplate, predecessorPlaceholder,
p.readPredecessor(sessionNameSVIDPrefix+sconeWorkloadInfo.CasSessionName))
session = strings.ReplaceAll(session, svidPlaceholder, pemToSconeInjectionFile(svid))
session = strings.ReplaceAll(session, svidKeyPlaceholder, pemToSconeInjectionFile(privateKey))
session = strings.ReplaceAll(session, sessionNameSelectorPlaceholder, sconeWorkloadInfo.CasSessionName)
session = strings.ReplaceAll(session, sessionHashSelectorPlaceholder, sconeWorkloadInfo.CasSessionHash)

return session
}

func (p *SecretsManagerPlugin) generateCASessionText(svidCa string) string {
var predecessorLine string
predecessor, err := p.readPredecessor(sessionNameCA)
if err != nil {
predecessorLine = ""
} else {
predecessorLine = "predecessor: " + predecessor
}

sessionTemplateP0 := "name: " + sessionNameCA + `
version: "0.3"
`
sessionTemplateP1 := `
secrets:
- name: spire-ca
kind: x509-ca
export_public: true
value: |
`
return sessionTemplateP0 + predecessorLine + sessionTemplateP1 + pemToSconeInjectionFile(svidCa)
session := strings.ReplaceAll(caBundleSessionTemplate, predecessorPlaceholder,
p.readPredecessor(sessionNameCA))
session = strings.ReplaceAll(session,
caTrustBundlePlaceholder,
pemToSconeInjectionFile(svidCa))
return session
}

func (p *SecretsManagerPlugin) generateFederatedBundlesSessionText(federatedBundles string) string {
var predecessorLine string
predecessor, err := p.readPredecessor(sessionNameFederatedBundles)
if err != nil {
predecessorLine = ""
} else {
predecessorLine = "predecessor: " + predecessor
}

sessionTemplateP0 := "name: " + sessionNameFederatedBundles + `
version: "0.3"
`
sessionTemplateP1 := `
secrets:
- name: spire-federated-bundles
kind: x509-ca
export_public: true
value: |
`
return sessionTemplateP0 + predecessorLine + sessionTemplateP1 + pemToSconeInjectionFile(federatedBundles)
session := strings.ReplaceAll(federatedBundlesSessionTemplate, predecessorPlaceholder,
p.readPredecessor(sessionNameFederatedBundles))
session = strings.ReplaceAll(session,
caTrustBundlePlaceholder,
pemToSconeInjectionFile(federatedBundles))
return session
}

func (p *SecretsManagerPlugin) doPostRequest(session string) (*http.Response, error) {
Expand Down Expand Up @@ -455,10 +462,11 @@ func (p *SecretsManagerPlugin) writePredecessor(sessionName string, predecessor
return err
}

func (p *SecretsManagerPlugin) readPredecessor(sessionName string) (string, error) {
func (p *SecretsManagerPlugin) readPredecessor(sessionName string) string {
predecessor, err := ioutil.ReadFile(p.config.PredecessorDir + "/" + sessionName)
if err != nil {
p.log.Warn("cannot read predecessor for session", err)
return "~"
}
return string(predecessor), nil
return string(predecessor)
}

0 comments on commit f9e6500

Please sign in to comment.