Merge pull request #1075 from smallstep/herman/remote-management-helm
Add `enableAdmin` and `enableACME` to Helm values.yml generation
This commit is contained in:
commit
a718359b7f
14 changed files with 948 additions and 16 deletions
|
@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||||
- Added name constraints evaluation and enforcement when issuing or renewing
|
- Added name constraints evaluation and enforcement when issuing or renewing
|
||||||
X.509 certificates.
|
X.509 certificates.
|
||||||
- Added provisioner webhooks for augmenting template data and authorizing certificate requests before signing.
|
- Added provisioner webhooks for augmenting template data and authorizing certificate requests before signing.
|
||||||
|
- Added automatic migration of provisioners when enabling remote managment.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- MySQL DSN parsing issues fixed with upgrade to [smallstep/nosql@v0.5.0](https://github.com/smallstep/nosql/releases/tag/v0.5.0).
|
- MySQL DSN parsing issues fixed with upgrade to [smallstep/nosql@v0.5.0](https://github.com/smallstep/nosql/releases/tag/v0.5.0).
|
||||||
|
|
|
@ -73,7 +73,7 @@ type Authority struct {
|
||||||
sshCAUserFederatedCerts []ssh.PublicKey
|
sshCAUserFederatedCerts []ssh.PublicKey
|
||||||
sshCAHostFederatedCerts []ssh.PublicKey
|
sshCAHostFederatedCerts []ssh.PublicKey
|
||||||
|
|
||||||
// Do not re-initialize
|
// If true, do not re-initialize
|
||||||
initOnce bool
|
initOnce bool
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
|
|
||||||
|
@ -91,8 +91,11 @@ type Authority struct {
|
||||||
|
|
||||||
adminMutex sync.RWMutex
|
adminMutex sync.RWMutex
|
||||||
|
|
||||||
// Do Not initialize the authority
|
// If true, do not initialize the authority
|
||||||
skipInit bool
|
skipInit bool
|
||||||
|
|
||||||
|
// If true, do not output initialization logs
|
||||||
|
quietInit bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Info contains information about the authority.
|
// Info contains information about the authority.
|
||||||
|
@ -600,20 +603,74 @@ func (a *Authority) init() error {
|
||||||
return admin.WrapErrorISE(err, "error loading provisioners to initialize authority")
|
return admin.WrapErrorISE(err, "error loading provisioners to initialize authority")
|
||||||
}
|
}
|
||||||
if len(provs) == 0 && !strings.EqualFold(a.config.AuthorityConfig.DeploymentType, "linked") {
|
if len(provs) == 0 && !strings.EqualFold(a.config.AuthorityConfig.DeploymentType, "linked") {
|
||||||
// Create First Provisioner
|
// Migration will currently only be kicked off once, because either one or more provisioners
|
||||||
prov, err := CreateFirstProvisioner(ctx, a.adminDB, string(a.password))
|
// are migrated or a default JWK provisioner will be created in the DB. It won't run for
|
||||||
if err != nil {
|
// linked or hosted deployments. Not for linked, because that case is explicitly checked
|
||||||
return admin.WrapErrorISE(err, "error creating first provisioner")
|
// for above. Not for hosted, because there'll be at least an existing OIDC provisioner.
|
||||||
|
var firstJWKProvisioner *linkedca.Provisioner
|
||||||
|
if len(a.config.AuthorityConfig.Provisioners) > 0 {
|
||||||
|
// Existing provisioners detected; try migrating them to DB storage.
|
||||||
|
a.initLogf("Starting migration of provisioners")
|
||||||
|
for _, p := range a.config.AuthorityConfig.Provisioners {
|
||||||
|
lp, err := ProvisionerToLinkedca(p)
|
||||||
|
if err != nil {
|
||||||
|
return admin.WrapErrorISE(err, "error transforming provisioner %q while migrating", p.GetName())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the provisioner to be migrated
|
||||||
|
if err := a.adminDB.CreateProvisioner(ctx, lp); err != nil {
|
||||||
|
return admin.WrapErrorISE(err, "error creating provisioner %q while migrating", p.GetName())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark the first JWK provisioner, so that it can be used for administration purposes
|
||||||
|
if firstJWKProvisioner == nil && lp.Type == linkedca.Provisioner_JWK {
|
||||||
|
firstJWKProvisioner = lp
|
||||||
|
a.initLogf("Migrated JWK provisioner %q with admin permissions", p.GetName())
|
||||||
|
} else {
|
||||||
|
a.initLogf("Migrated %s provisioner %q", p.GetType(), p.GetName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c := a.config
|
||||||
|
if c.WasLoadedFromFile() {
|
||||||
|
// The provisioners in the configuration file can be deleted from
|
||||||
|
// the file by editing it. Automatic rewriting of the file was considered
|
||||||
|
// to be too surprising for users and not the right solution for all
|
||||||
|
// use cases, so we leave it up to users to this themselves.
|
||||||
|
a.initLogf("Provisioners that were migrated can now be removed from `ca.json` by editing it")
|
||||||
|
}
|
||||||
|
|
||||||
|
a.initLogf("Finished migrating provisioners")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create first admin
|
// Create first JWK provisioner for remote administration purposes if none exists yet
|
||||||
|
if firstJWKProvisioner == nil {
|
||||||
|
firstJWKProvisioner, err = CreateFirstProvisioner(ctx, a.adminDB, string(a.password))
|
||||||
|
if err != nil {
|
||||||
|
return admin.WrapErrorISE(err, "error creating first provisioner")
|
||||||
|
}
|
||||||
|
a.initLogf("Created JWK provisioner %q with admin permissions", firstJWKProvisioner.GetName())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create first super admin, belonging to the first JWK provisioner
|
||||||
|
// TODO(hs): pass a user-provided first super admin subject to here. With `ca init` it's
|
||||||
|
// added to the DB immediately if using remote management. But when migrating from
|
||||||
|
// ca.json to the DB, this option doesn't exist. Adding a flag just to do it during
|
||||||
|
// migration isn't nice. We could opt for a user to change it afterwards. There exist
|
||||||
|
// cases in which creation of `step` could lock out a user from API access. This is the
|
||||||
|
// case if `step` isn't allowed to be signed by Name Constraints or the X.509 policy.
|
||||||
|
// We have protection for that when creating and updating a policy, but if a policy or
|
||||||
|
// Name Constraints are in use at the time of migration, that could lock the user out.
|
||||||
|
superAdminSubject := "step"
|
||||||
if err := a.adminDB.CreateAdmin(ctx, &linkedca.Admin{
|
if err := a.adminDB.CreateAdmin(ctx, &linkedca.Admin{
|
||||||
ProvisionerId: prov.Id,
|
ProvisionerId: firstJWKProvisioner.Id,
|
||||||
Subject: "step",
|
Subject: superAdminSubject,
|
||||||
Type: linkedca.Admin_SUPER_ADMIN,
|
Type: linkedca.Admin_SUPER_ADMIN,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return admin.WrapErrorISE(err, "error creating first admin")
|
return admin.WrapErrorISE(err, "error creating first admin")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.initLogf("Created super admin %q for JWK provisioner %q", superAdminSubject, firstJWKProvisioner.GetName())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,6 +720,14 @@ func (a *Authority) init() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initLogf is used to log initialization information. The output
|
||||||
|
// can be disabled by starting the CA with the `--quiet` flag.
|
||||||
|
func (a *Authority) initLogf(format string, v ...any) {
|
||||||
|
if !a.quietInit {
|
||||||
|
log.Printf(format, v...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetID returns the define authority id or a zero uuid.
|
// GetID returns the define authority id or a zero uuid.
|
||||||
func (a *Authority) GetID() string {
|
func (a *Authority) GetID() string {
|
||||||
const zeroUUID = "00000000-0000-0000-0000-000000000000"
|
const zeroUUID = "00000000-0000-0000-0000-000000000000"
|
||||||
|
|
|
@ -73,6 +73,9 @@ type Config struct {
|
||||||
Templates *templates.Templates `json:"templates,omitempty"`
|
Templates *templates.Templates `json:"templates,omitempty"`
|
||||||
CommonName string `json:"commonName,omitempty"`
|
CommonName string `json:"commonName,omitempty"`
|
||||||
SkipValidation bool `json:"-"`
|
SkipValidation bool `json:"-"`
|
||||||
|
|
||||||
|
// Keeps record of the filename the Config is read from
|
||||||
|
loadedFromFilepath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ASN1DN contains ASN1.DN attributes that are used in Subject and Issuer
|
// ASN1DN contains ASN1.DN attributes that are used in Subject and Issuer
|
||||||
|
@ -163,6 +166,10 @@ func LoadConfiguration(filename string) (*Config, error) {
|
||||||
return nil, errors.Wrapf(err, "error parsing %s", filename)
|
return nil, errors.Wrapf(err, "error parsing %s", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store filename that was read to populate Config
|
||||||
|
c.loadedFromFilepath = filename
|
||||||
|
|
||||||
|
// initialize the Config
|
||||||
c.Init()
|
c.Init()
|
||||||
|
|
||||||
return &c, nil
|
return &c, nil
|
||||||
|
@ -199,6 +206,30 @@ func (c *Config) Save(filename string) error {
|
||||||
return errors.Wrapf(enc.Encode(c), "error writing %s", filename)
|
return errors.Wrapf(enc.Encode(c), "error writing %s", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Commit saves the current configuration to the same
|
||||||
|
// file it was initially loaded from.
|
||||||
|
//
|
||||||
|
// TODO(hs): rename Save() to WriteTo() and replace this
|
||||||
|
// with Save()? Or is Commit clear enough.
|
||||||
|
func (c *Config) Commit() error {
|
||||||
|
if !c.WasLoadedFromFile() {
|
||||||
|
return errors.New("cannot commit configuration if not loaded from file")
|
||||||
|
}
|
||||||
|
return c.Save(c.loadedFromFilepath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WasLoadedFromFile returns whether or not the Config was
|
||||||
|
// loaded from a file.
|
||||||
|
func (c *Config) WasLoadedFromFile() bool {
|
||||||
|
return c.loadedFromFilepath != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filepath returns the path to the file the Config was
|
||||||
|
// loaded from.
|
||||||
|
func (c *Config) Filepath() string {
|
||||||
|
return c.loadedFromFilepath
|
||||||
|
}
|
||||||
|
|
||||||
// Validate validates the configuration.
|
// Validate validates the configuration.
|
||||||
func (c *Config) Validate() error {
|
func (c *Config) Validate() error {
|
||||||
switch {
|
switch {
|
||||||
|
|
|
@ -86,6 +86,14 @@ func WithDatabase(d db.AuthDB) Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithQuietInit disables log output when the authority is initialized.
|
||||||
|
func WithQuietInit() Option {
|
||||||
|
return func(a *Authority) error {
|
||||||
|
a.quietInit = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithWebhookClient sets the http.Client to be used for outbound requests.
|
// WithWebhookClient sets the http.Client to be used for outbound requests.
|
||||||
func WithWebhookClient(c *http.Client) Option {
|
func WithWebhookClient(c *http.Client) Option {
|
||||||
return func(a *Authority) error {
|
return func(a *Authority) error {
|
||||||
|
|
13
ca/ca.go
13
ca/ca.go
|
@ -156,6 +156,10 @@ func (ca *CA) Init(cfg *config.Config) (*CA, error) {
|
||||||
opts = append(opts, authority.WithDatabase(ca.opts.database))
|
opts = append(opts, authority.WithDatabase(ca.opts.database))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ca.opts.quiet {
|
||||||
|
opts = append(opts, authority.WithQuietInit())
|
||||||
|
}
|
||||||
|
|
||||||
webhookTransport := http.DefaultTransport.(*http.Transport).Clone()
|
webhookTransport := http.DefaultTransport.(*http.Transport).Clone()
|
||||||
opts = append(opts, authority.WithWebhookClient(&http.Client{Transport: webhookTransport}))
|
opts = append(opts, authority.WithWebhookClient(&http.Client{Transport: webhookTransport}))
|
||||||
|
|
||||||
|
@ -345,7 +349,7 @@ func (ca *CA) Run() error {
|
||||||
if step.Contexts().GetCurrent() != nil {
|
if step.Contexts().GetCurrent() != nil {
|
||||||
log.Printf("Current context: %s", step.Contexts().GetCurrent().Name)
|
log.Printf("Current context: %s", step.Contexts().GetCurrent().Name)
|
||||||
}
|
}
|
||||||
log.Printf("Config file: %s", ca.opts.configFile)
|
log.Printf("Config file: %s", ca.getConfigFileOutput())
|
||||||
baseURL := fmt.Sprintf("https://%s%s",
|
baseURL := fmt.Sprintf("https://%s%s",
|
||||||
authorityInfo.DNSNames[0],
|
authorityInfo.DNSNames[0],
|
||||||
ca.config.Address[strings.LastIndex(ca.config.Address, ":"):])
|
ca.config.Address[strings.LastIndex(ca.config.Address, ":"):])
|
||||||
|
@ -565,3 +569,10 @@ func dumpRoutes(mux chi.Routes) {
|
||||||
fmt.Printf("Logging err: %s\n", err.Error())
|
fmt.Printf("Logging err: %s\n", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ca *CA) getConfigFileOutput() string {
|
||||||
|
if ca.config.WasLoadedFromFile() {
|
||||||
|
return ca.config.Filepath()
|
||||||
|
}
|
||||||
|
return "loaded from token"
|
||||||
|
}
|
||||||
|
|
36
pki/helm.go
36
pki/helm.go
|
@ -17,6 +17,7 @@ type helmVariables struct {
|
||||||
Defaults *linkedca.Defaults
|
Defaults *linkedca.Defaults
|
||||||
Password string
|
Password string
|
||||||
EnableSSH bool
|
EnableSSH bool
|
||||||
|
EnableAdmin bool
|
||||||
TLS authconfig.TLSOptions
|
TLS authconfig.TLSOptions
|
||||||
Provisioners []provisioner.Interface
|
Provisioners []provisioner.Interface
|
||||||
}
|
}
|
||||||
|
@ -34,14 +35,39 @@ func (p *PKI) WriteHelmTemplate(w io.Writer) error {
|
||||||
p.Ssh = nil
|
p.Ssh = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert provisioner to ca.json
|
// Convert provisioners to ca.json representation
|
||||||
provisioners := make([]provisioner.Interface, len(p.Authority.Provisioners))
|
provisioners := []provisioner.Interface{}
|
||||||
for i, p := range p.Authority.Provisioners {
|
for _, p := range p.Authority.Provisioners {
|
||||||
pp, err := authority.ProvisionerToCertificates(p)
|
pp, err := authority.ProvisionerToCertificates(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
provisioners[i] = pp
|
provisioners = append(provisioners, pp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add default ACME provisioner if enabled. Note that this logic is similar
|
||||||
|
// to what's in p.GenerateConfig(), but that codepath isn't taken when
|
||||||
|
// writing the Helm template. The default JWK provisioner is added earlier in
|
||||||
|
// the process and that's part of the provisioners above.
|
||||||
|
// TODO(hs): consider refactoring the initialization, so that this becomes
|
||||||
|
// easier to reason about and maintain.
|
||||||
|
if p.options.enableACME {
|
||||||
|
provisioners = append(provisioners, &provisioner.ACME{
|
||||||
|
Type: "ACME",
|
||||||
|
Name: "acme",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add default SSHPOP provisioner if enabled. Similar to the above, this is
|
||||||
|
// the same as what happens in p.GenerateConfig().
|
||||||
|
if p.options.enableSSH {
|
||||||
|
provisioners = append(provisioners, &provisioner.SSHPOP{
|
||||||
|
Type: "SSHPOP",
|
||||||
|
Name: "sshpop",
|
||||||
|
Claims: &provisioner.Claims{
|
||||||
|
EnableSSHCA: &p.options.enableSSH,
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tmpl.Execute(w, helmVariables{
|
if err := tmpl.Execute(w, helmVariables{
|
||||||
|
@ -49,6 +75,7 @@ func (p *PKI) WriteHelmTemplate(w io.Writer) error {
|
||||||
Defaults: &p.Defaults,
|
Defaults: &p.Defaults,
|
||||||
Password: "",
|
Password: "",
|
||||||
EnableSSH: p.options.enableSSH,
|
EnableSSH: p.options.enableSSH,
|
||||||
|
EnableAdmin: p.options.enableAdmin,
|
||||||
TLS: authconfig.DefaultTLSOptions,
|
TLS: authconfig.DefaultTLSOptions,
|
||||||
Provisioners: provisioners,
|
Provisioners: provisioners,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
@ -88,6 +115,7 @@ inject:
|
||||||
type: badgerv2
|
type: badgerv2
|
||||||
dataSource: /home/step/db
|
dataSource: /home/step/db
|
||||||
authority:
|
authority:
|
||||||
|
enableAdmin: {{ .EnableAdmin }}
|
||||||
provisioners:
|
provisioners:
|
||||||
{{- range .Provisioners }}
|
{{- range .Provisioners }}
|
||||||
- {{ . | toJson }}
|
- {{ . | toJson }}
|
||||||
|
|
232
pki/helm_test.go
Normal file
232
pki/helm_test.go
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
package pki
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"encoding/pem"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"go.step.sm/crypto/jose"
|
||||||
|
"go.step.sm/linkedca"
|
||||||
|
|
||||||
|
"github.com/smallstep/certificates/cas/apiv1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPKI_WriteHelmTemplate(t *testing.T) {
|
||||||
|
var preparePKI = func(t *testing.T, opts ...Option) *PKI {
|
||||||
|
o := apiv1.Options{
|
||||||
|
Type: "softcas",
|
||||||
|
IsCreator: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add default WithHelm option
|
||||||
|
opts = append(opts, WithHelm())
|
||||||
|
|
||||||
|
// TODO(hs): invoking `New` doesn't perform all operations that are executed
|
||||||
|
// when `ca init --helm` is executed. Ideally this logic should be handled
|
||||||
|
// in one place and probably inside of the PKI initialization. For testing
|
||||||
|
// purposes the missing operations to fill a Helm template fully are faked
|
||||||
|
// by `setKeyPair`, `setCertificates` and `setSSHSigningKeys`
|
||||||
|
p, err := New(o, opts...)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// setKeyPair sets a predefined JWK and a default JWK provisioner. This is one
|
||||||
|
// of the things performed in the `ca init` code that's not part of `New`, but
|
||||||
|
// performed after that in p.GenerateKeyPairs`. We're currently using the same
|
||||||
|
// JWK for every test to keep test variance small: we're not testing JWK generation
|
||||||
|
// here after all. It's a bit dangerous to redefine the function here, but it's
|
||||||
|
// the simplest way to make this fully testable without refactoring the init now.
|
||||||
|
// The password for the predefined encrypted key is \x01\x03\x03\x07.
|
||||||
|
setKeyPair(t, p)
|
||||||
|
|
||||||
|
// setCertificates sets some static intermediate and root CA certificate bytes. It
|
||||||
|
// replaces the logic executed in `p.GenerateRootCertificate`, `p.WriteRootCertificate`,
|
||||||
|
// and `p.GenerateIntermediateCertificate`.
|
||||||
|
setCertificates(t, p)
|
||||||
|
|
||||||
|
// setSSHSigningKeys sets predefined SSH user and host certificate and key bytes.
|
||||||
|
// This replaces the logic in `p.GenerateSSHSigningKeys`
|
||||||
|
setSSHSigningKeys(t, p)
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
type test struct {
|
||||||
|
pki *PKI
|
||||||
|
testFile string
|
||||||
|
wantErr bool
|
||||||
|
}
|
||||||
|
var tests = map[string]func(t *testing.T) test{
|
||||||
|
"ok/simple": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
pki: preparePKI(t),
|
||||||
|
testFile: "testdata/helm/simple.yml",
|
||||||
|
wantErr: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ok/with-provisioner": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
pki: preparePKI(t, WithProvisioner("a-provisioner")),
|
||||||
|
testFile: "testdata/helm/with-provisioner.yml",
|
||||||
|
wantErr: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ok/with-acme": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
pki: preparePKI(t, WithACME()),
|
||||||
|
testFile: "testdata/helm/with-acme.yml",
|
||||||
|
wantErr: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ok/with-admin": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
pki: preparePKI(t, WithAdmin()),
|
||||||
|
testFile: "testdata/helm/with-admin.yml",
|
||||||
|
wantErr: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ok/with-ssh": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
pki: preparePKI(t, WithSSH()),
|
||||||
|
testFile: "testdata/helm/with-ssh.yml",
|
||||||
|
wantErr: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ok/with-ssh-and-acme": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
pki: preparePKI(t, WithSSH(), WithACME()),
|
||||||
|
testFile: "testdata/helm/with-ssh-and-acme.yml",
|
||||||
|
wantErr: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fail/authority.ProvisionerToCertificates": func(t *testing.T) test {
|
||||||
|
pki := preparePKI(t)
|
||||||
|
pki.Authority.Provisioners = append(pki.Authority.Provisioners,
|
||||||
|
&linkedca.Provisioner{
|
||||||
|
Type: linkedca.Provisioner_JWK,
|
||||||
|
Name: "Broken JWK",
|
||||||
|
Details: nil,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return test{
|
||||||
|
pki: pki,
|
||||||
|
wantErr: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, run := range tests {
|
||||||
|
tc := run(t)
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
|
||||||
|
w := &bytes.Buffer{}
|
||||||
|
if err := tc.pki.WriteHelmTemplate(w); (err != nil) != tc.wantErr {
|
||||||
|
t.Errorf("PKI.WriteHelmTemplate() error = %v, wantErr %v", err, tc.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tc.wantErr {
|
||||||
|
// don't compare output if an error was expected on output
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
wantBytes, err := os.ReadFile(tc.testFile)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
if diff := cmp.Diff(wantBytes, w.Bytes()); diff != "" {
|
||||||
|
t.Logf("Generated Helm template did not match reference %q\n", tc.testFile)
|
||||||
|
t.Errorf("Diff follows:\n%s\n", diff)
|
||||||
|
t.Errorf("Full output:\n%s\n", w.Bytes())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setKeyPair sets a predefined JWK and a default JWK provisioner.
|
||||||
|
func setKeyPair(t *testing.T, p *PKI) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
p.ottPublicKey, err = jose.ParseKey([]byte(`{"use":"sig","kty":"EC","kid":"zsUmysmDVoGJ71YoPHyZ-68tNihDaDaO5Mu7xX3M-_I","crv":"P-256","alg":"ES256","x":"Pqnua4CzqKz6ua41J3yeWZ1sRkGt0UlCkbHv8H2DGuY","y":"UhoZ_2ItDen9KQTcjay-ph-SBXH0mwqhHyvrrqIFDOI"}`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.ottPrivateKey, err = jose.ParseEncrypted("eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiZjVvdGVRS2hvOXl4MmQtSGlMZi05QSJ9.eYA6tt3fNuUpoxKWDT7P0Lbn2juxhEbTxEnwEMbjlYLLQ3sxL-dYTA.ven-FhmdjlC9itH0.a2jRTarN9vPd6F_mWnNBlOn6KbfMjCApmci2t65XbAsLzYFzhI_79Ykm5ueMYTupWLTjBJctl-g51ZHmsSB55pStbpoyyLNAsUX2E1fTmHe-Ni8bRrspwLv15FoN1Xo1g0mpR-ufWIFxOsW-QIfnMmMIIkygVuHFXmg2tFpzTNNG5aS29K3dN2nyk0WJrdIq79hZSTqVkkBU25Yu3A46sgjcM86XcIJJ2XUEih_KWEa6T1YrkixGu96pebjVqbO0R6dbDckfPF7FqNnwPHVtb1ACFpEYoOJVIbUCMaARBpWsxYhjJZlEM__XA46l8snFQDkNY3CdN0p1_gF3ckA.JLmq9nmu1h9oUi1S8ZxYjA")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var claims *linkedca.Claims
|
||||||
|
if p.options.enableSSH {
|
||||||
|
claims = &linkedca.Claims{
|
||||||
|
Ssh: &linkedca.SSHClaims{
|
||||||
|
Enabled: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
publicKey, err := json.Marshal(p.ottPublicKey)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
encryptedKey, err := p.ottPrivateKey.CompactSerialize()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
p.Authority.Provisioners = append(p.Authority.Provisioners, &linkedca.Provisioner{
|
||||||
|
Type: linkedca.Provisioner_JWK,
|
||||||
|
Name: p.options.provisioner,
|
||||||
|
Claims: claims,
|
||||||
|
Details: &linkedca.ProvisionerDetails{
|
||||||
|
Data: &linkedca.ProvisionerDetails_JWK{
|
||||||
|
JWK: &linkedca.JWKProvisioner{
|
||||||
|
PublicKey: publicKey,
|
||||||
|
EncryptedPrivateKey: []byte(encryptedKey),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// setCertificates sets some static, gibberish intermediate and root CA certificate and key bytes.
|
||||||
|
func setCertificates(t *testing.T, p *PKI) {
|
||||||
|
raw := []byte("these are just some fake root CA cert bytes")
|
||||||
|
p.Files[p.Root[0]] = encodeCertificate(&x509.Certificate{Raw: raw})
|
||||||
|
p.Files[p.RootKey[0]] = pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "EC PRIVATE KEY",
|
||||||
|
Bytes: []byte("these are just some fake root CA key bytes"),
|
||||||
|
})
|
||||||
|
p.Files[p.Intermediate] = encodeCertificate(&x509.Certificate{Raw: []byte("these are just some fake intermediate CA cert bytes")})
|
||||||
|
p.Files[p.IntermediateKey] = pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "EC PRIVATE KEY",
|
||||||
|
Bytes: []byte("these are just some fake intermediate CA key bytes"),
|
||||||
|
})
|
||||||
|
sum := sha256.Sum256(raw)
|
||||||
|
p.Defaults.Fingerprint = strings.ToLower(hex.EncodeToString(sum[:]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// setSSHSigningKeys sets some static, gibberish ssh user and host CA certificate and key bytes.
|
||||||
|
func setSSHSigningKeys(t *testing.T, p *PKI) {
|
||||||
|
|
||||||
|
if !p.options.enableSSH {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Files[p.Ssh.HostKey] = pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "EC PRIVATE KEY",
|
||||||
|
Bytes: []byte("fake ssh host key bytes"),
|
||||||
|
})
|
||||||
|
p.Files[p.Ssh.HostPublicKey] = []byte("ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ0IdS5sZm6KITBMZLEJD6b5ROVraYHcAOr3feFel8r1Wp4DRPR1oU0W00J/zjNBRBbANlJoYN4x/8WNNVZ49Ms=")
|
||||||
|
p.Files[p.Ssh.UserKey] = pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "EC PRIVATE KEY",
|
||||||
|
Bytes: []byte("fake ssh user key bytes"),
|
||||||
|
})
|
||||||
|
p.Files[p.Ssh.UserPublicKey] = []byte("ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEWA1qUxaGwVNErsvEOGe2d6TvLMF+aiVpuOiIEvpMJ3JeJmecLQctjWqeIbpSvy6/gRa7c82Ge5rLlapYmOChs=")
|
||||||
|
}
|
26
pki/pki.go
26
pki/pki.go
|
@ -176,6 +176,7 @@ func GetProvisionerKey(caURL, rootFile, kid string) (string, error) {
|
||||||
|
|
||||||
type options struct {
|
type options struct {
|
||||||
provisioner string
|
provisioner string
|
||||||
|
superAdminSubject string
|
||||||
pkiOnly bool
|
pkiOnly bool
|
||||||
enableACME bool
|
enableACME bool
|
||||||
enableSSH bool
|
enableSSH bool
|
||||||
|
@ -220,6 +221,15 @@ func WithProvisioner(s string) Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSuperAdminSubject defines the subject of the first
|
||||||
|
// super admin for use with the Admin API. The admin will belong
|
||||||
|
// to the first JWK provisioner.
|
||||||
|
func WithSuperAdminSubject(s string) Option {
|
||||||
|
return func(p *PKI) {
|
||||||
|
p.options.superAdminSubject = s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithPKIOnly will only generate the PKI without the step-ca config files.
|
// WithPKIOnly will only generate the PKI without the step-ca config files.
|
||||||
func WithPKIOnly() Option {
|
func WithPKIOnly() Option {
|
||||||
return func(p *PKI) {
|
return func(p *PKI) {
|
||||||
|
@ -307,6 +317,9 @@ type PKI struct {
|
||||||
|
|
||||||
// New creates a new PKI configuration.
|
// New creates a new PKI configuration.
|
||||||
func New(o apiv1.Options, opts ...Option) (*PKI, error) {
|
func New(o apiv1.Options, opts ...Option) (*PKI, error) {
|
||||||
|
// TODO(hs): invoking `New` with a context active will use values from
|
||||||
|
// that CA context while generating the context. Thay may or may not
|
||||||
|
// be fully expected and/or what we want. Check that.
|
||||||
currentCtx := step.Contexts().GetCurrent()
|
currentCtx := step.Contexts().GetCurrent()
|
||||||
caService, err := cas.New(context.Background(), o)
|
caService, err := cas.New(context.Background(), o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -645,7 +658,7 @@ func (p *PKI) GetCertificateAuthority() error {
|
||||||
// SSH user certificates and a private key used for signing host certificates.
|
// SSH user certificates and a private key used for signing host certificates.
|
||||||
func (p *PKI) GenerateSSHSigningKeys(password []byte) error {
|
func (p *PKI) GenerateSSHSigningKeys(password []byte) error {
|
||||||
// Enable SSH
|
// Enable SSH
|
||||||
p.options.enableSSH = true
|
p.options.enableSSH = true // TODO(hs): change this function to not mutate configuration state
|
||||||
|
|
||||||
// Create SSH key used to sign host certificates. Using
|
// Create SSH key used to sign host certificates. Using
|
||||||
// kmsapi.UnspecifiedSignAlgorithm will default to the default algorithm.
|
// kmsapi.UnspecifiedSignAlgorithm will default to the default algorithm.
|
||||||
|
@ -883,6 +896,11 @@ func (p *PKI) GenerateConfig(opt ...ConfigOption) (*authconfig.Config, error) {
|
||||||
//
|
//
|
||||||
// Note that we might want to be able to define the database as a
|
// Note that we might want to be able to define the database as a
|
||||||
// flag in `step ca init` so we can write to the proper place.
|
// flag in `step ca init` so we can write to the proper place.
|
||||||
|
//
|
||||||
|
// TODO(hs): the logic for creating the provisioners and the super admin
|
||||||
|
// is similar to what's done when automatically migrating the provisioners.
|
||||||
|
// This is related to the existing comment above. Refactor this to exist in
|
||||||
|
// a single place and ensure it happens only once.
|
||||||
_db, err := db.New(cfg.DB)
|
_db, err := db.New(cfg.DB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -906,9 +924,13 @@ func (p *PKI) GenerateConfig(opt ...ConfigOption) (*authconfig.Config, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add the first provisioner as an admin.
|
// Add the first provisioner as an admin.
|
||||||
|
superAdminSubject := "step"
|
||||||
|
if p.options.superAdminSubject != "" {
|
||||||
|
superAdminSubject = p.options.superAdminSubject
|
||||||
|
}
|
||||||
if err := adminDB.CreateAdmin(context.Background(), &linkedca.Admin{
|
if err := adminDB.CreateAdmin(context.Background(), &linkedca.Admin{
|
||||||
AuthorityId: admin.DefaultAuthorityID,
|
AuthorityId: admin.DefaultAuthorityID,
|
||||||
Subject: "step",
|
Subject: superAdminSubject,
|
||||||
Type: linkedca.Admin_SUPER_ADMIN,
|
Type: linkedca.Admin_SUPER_ADMIN,
|
||||||
ProvisionerId: adminID,
|
ProvisionerId: adminID,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
|
81
pki/testdata/helm/simple.yml
vendored
Normal file
81
pki/testdata/helm/simple.yml
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# Helm template
|
||||||
|
inject:
|
||||||
|
enabled: true
|
||||||
|
# Config contains the configuration files ca.json and defaults.json
|
||||||
|
config:
|
||||||
|
files:
|
||||||
|
ca.json:
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
federateRoots: []
|
||||||
|
crt: /home/step/certs/intermediate_ca.crt
|
||||||
|
key: /home/step/secrets/intermediate_ca_key
|
||||||
|
address: 127.0.0.1:9000
|
||||||
|
dnsNames:
|
||||||
|
- 127.0.0.1
|
||||||
|
logger:
|
||||||
|
format: json
|
||||||
|
db:
|
||||||
|
type: badgerv2
|
||||||
|
dataSource: /home/step/db
|
||||||
|
authority:
|
||||||
|
enableAdmin: false
|
||||||
|
provisioners:
|
||||||
|
- {"type":"JWK","name":"step-cli","key":{"use":"sig","kty":"EC","kid":"zsUmysmDVoGJ71YoPHyZ-68tNihDaDaO5Mu7xX3M-_I","crv":"P-256","alg":"ES256","x":"Pqnua4CzqKz6ua41J3yeWZ1sRkGt0UlCkbHv8H2DGuY","y":"UhoZ_2ItDen9KQTcjay-ph-SBXH0mwqhHyvrrqIFDOI"},"encryptedKey":"eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiZjVvdGVRS2hvOXl4MmQtSGlMZi05QSJ9.eYA6tt3fNuUpoxKWDT7P0Lbn2juxhEbTxEnwEMbjlYLLQ3sxL-dYTA.ven-FhmdjlC9itH0.a2jRTarN9vPd6F_mWnNBlOn6KbfMjCApmci2t65XbAsLzYFzhI_79Ykm5ueMYTupWLTjBJctl-g51ZHmsSB55pStbpoyyLNAsUX2E1fTmHe-Ni8bRrspwLv15FoN1Xo1g0mpR-ufWIFxOsW-QIfnMmMIIkygVuHFXmg2tFpzTNNG5aS29K3dN2nyk0WJrdIq79hZSTqVkkBU25Yu3A46sgjcM86XcIJJ2XUEih_KWEa6T1YrkixGu96pebjVqbO0R6dbDckfPF7FqNnwPHVtb1ACFpEYoOJVIbUCMaARBpWsxYhjJZlEM__XA46l8snFQDkNY3CdN0p1_gF3ckA.JLmq9nmu1h9oUi1S8ZxYjA","options":{"x509":{},"ssh":{}}}
|
||||||
|
tls:
|
||||||
|
cipherSuites:
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
minVersion: 1.2
|
||||||
|
maxVersion: 1.3
|
||||||
|
renegotiation: false
|
||||||
|
|
||||||
|
defaults.json:
|
||||||
|
ca-url: https://127.0.0.1
|
||||||
|
ca-config: /home/step/config/ca.json
|
||||||
|
fingerprint: e543cad8e9f6417076bb5aed3471c588152118aac1e0ca7984a43ee7f76da5e3
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
|
||||||
|
# Certificates contains the root and intermediate certificate and
|
||||||
|
# optionally the SSH host and user public keys
|
||||||
|
certificates:
|
||||||
|
# intermediate_ca contains the text of the intermediate CA Certificate
|
||||||
|
intermediate_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBjZXJ0IGJ5
|
||||||
|
dGVz
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca contains the text of the root CA Certificate
|
||||||
|
root_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0EgY2VydCBieXRlcw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# Secrets contains the root and intermediate keys and optionally the SSH
|
||||||
|
# private keys
|
||||||
|
secrets:
|
||||||
|
# ca_password contains the password used to encrypt x509.intermediate_ca_key, ssh.host_ca_key and ssh.user_ca_key
|
||||||
|
# This value must be base64 encoded.
|
||||||
|
ca_password:
|
||||||
|
provisioner_password:
|
||||||
|
|
||||||
|
x509:
|
||||||
|
# intermediate_ca_key contains the contents of your encrypted intermediate CA key
|
||||||
|
intermediate_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBrZXkgYnl0
|
||||||
|
ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca_key contains the contents of your encrypted root CA key
|
||||||
|
# Note that this value can be omitted without impacting the functionality of step-certificates
|
||||||
|
# If supplied, this should be encrypted using a unique password that is not used for encrypting
|
||||||
|
# the intermediate_ca_key, ssh.host_ca_key or ssh.user_ca_key.
|
||||||
|
root_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0Ega2V5IGJ5dGVz
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
82
pki/testdata/helm/with-acme.yml
vendored
Normal file
82
pki/testdata/helm/with-acme.yml
vendored
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
# Helm template
|
||||||
|
inject:
|
||||||
|
enabled: true
|
||||||
|
# Config contains the configuration files ca.json and defaults.json
|
||||||
|
config:
|
||||||
|
files:
|
||||||
|
ca.json:
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
federateRoots: []
|
||||||
|
crt: /home/step/certs/intermediate_ca.crt
|
||||||
|
key: /home/step/secrets/intermediate_ca_key
|
||||||
|
address: 127.0.0.1:9000
|
||||||
|
dnsNames:
|
||||||
|
- 127.0.0.1
|
||||||
|
logger:
|
||||||
|
format: json
|
||||||
|
db:
|
||||||
|
type: badgerv2
|
||||||
|
dataSource: /home/step/db
|
||||||
|
authority:
|
||||||
|
enableAdmin: false
|
||||||
|
provisioners:
|
||||||
|
- {"type":"JWK","name":"step-cli","key":{"use":"sig","kty":"EC","kid":"zsUmysmDVoGJ71YoPHyZ-68tNihDaDaO5Mu7xX3M-_I","crv":"P-256","alg":"ES256","x":"Pqnua4CzqKz6ua41J3yeWZ1sRkGt0UlCkbHv8H2DGuY","y":"UhoZ_2ItDen9KQTcjay-ph-SBXH0mwqhHyvrrqIFDOI"},"encryptedKey":"eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiZjVvdGVRS2hvOXl4MmQtSGlMZi05QSJ9.eYA6tt3fNuUpoxKWDT7P0Lbn2juxhEbTxEnwEMbjlYLLQ3sxL-dYTA.ven-FhmdjlC9itH0.a2jRTarN9vPd6F_mWnNBlOn6KbfMjCApmci2t65XbAsLzYFzhI_79Ykm5ueMYTupWLTjBJctl-g51ZHmsSB55pStbpoyyLNAsUX2E1fTmHe-Ni8bRrspwLv15FoN1Xo1g0mpR-ufWIFxOsW-QIfnMmMIIkygVuHFXmg2tFpzTNNG5aS29K3dN2nyk0WJrdIq79hZSTqVkkBU25Yu3A46sgjcM86XcIJJ2XUEih_KWEa6T1YrkixGu96pebjVqbO0R6dbDckfPF7FqNnwPHVtb1ACFpEYoOJVIbUCMaARBpWsxYhjJZlEM__XA46l8snFQDkNY3CdN0p1_gF3ckA.JLmq9nmu1h9oUi1S8ZxYjA","options":{"x509":{},"ssh":{}}}
|
||||||
|
- {"type":"ACME","name":"acme"}
|
||||||
|
tls:
|
||||||
|
cipherSuites:
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
minVersion: 1.2
|
||||||
|
maxVersion: 1.3
|
||||||
|
renegotiation: false
|
||||||
|
|
||||||
|
defaults.json:
|
||||||
|
ca-url: https://127.0.0.1
|
||||||
|
ca-config: /home/step/config/ca.json
|
||||||
|
fingerprint: e543cad8e9f6417076bb5aed3471c588152118aac1e0ca7984a43ee7f76da5e3
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
|
||||||
|
# Certificates contains the root and intermediate certificate and
|
||||||
|
# optionally the SSH host and user public keys
|
||||||
|
certificates:
|
||||||
|
# intermediate_ca contains the text of the intermediate CA Certificate
|
||||||
|
intermediate_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBjZXJ0IGJ5
|
||||||
|
dGVz
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca contains the text of the root CA Certificate
|
||||||
|
root_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0EgY2VydCBieXRlcw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# Secrets contains the root and intermediate keys and optionally the SSH
|
||||||
|
# private keys
|
||||||
|
secrets:
|
||||||
|
# ca_password contains the password used to encrypt x509.intermediate_ca_key, ssh.host_ca_key and ssh.user_ca_key
|
||||||
|
# This value must be base64 encoded.
|
||||||
|
ca_password:
|
||||||
|
provisioner_password:
|
||||||
|
|
||||||
|
x509:
|
||||||
|
# intermediate_ca_key contains the contents of your encrypted intermediate CA key
|
||||||
|
intermediate_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBrZXkgYnl0
|
||||||
|
ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca_key contains the contents of your encrypted root CA key
|
||||||
|
# Note that this value can be omitted without impacting the functionality of step-certificates
|
||||||
|
# If supplied, this should be encrypted using a unique password that is not used for encrypting
|
||||||
|
# the intermediate_ca_key, ssh.host_ca_key or ssh.user_ca_key.
|
||||||
|
root_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0Ega2V5IGJ5dGVz
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
81
pki/testdata/helm/with-admin.yml
vendored
Normal file
81
pki/testdata/helm/with-admin.yml
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# Helm template
|
||||||
|
inject:
|
||||||
|
enabled: true
|
||||||
|
# Config contains the configuration files ca.json and defaults.json
|
||||||
|
config:
|
||||||
|
files:
|
||||||
|
ca.json:
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
federateRoots: []
|
||||||
|
crt: /home/step/certs/intermediate_ca.crt
|
||||||
|
key: /home/step/secrets/intermediate_ca_key
|
||||||
|
address: 127.0.0.1:9000
|
||||||
|
dnsNames:
|
||||||
|
- 127.0.0.1
|
||||||
|
logger:
|
||||||
|
format: json
|
||||||
|
db:
|
||||||
|
type: badgerv2
|
||||||
|
dataSource: /home/step/db
|
||||||
|
authority:
|
||||||
|
enableAdmin: true
|
||||||
|
provisioners:
|
||||||
|
- {"type":"JWK","name":"step-cli","key":{"use":"sig","kty":"EC","kid":"zsUmysmDVoGJ71YoPHyZ-68tNihDaDaO5Mu7xX3M-_I","crv":"P-256","alg":"ES256","x":"Pqnua4CzqKz6ua41J3yeWZ1sRkGt0UlCkbHv8H2DGuY","y":"UhoZ_2ItDen9KQTcjay-ph-SBXH0mwqhHyvrrqIFDOI"},"encryptedKey":"eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiZjVvdGVRS2hvOXl4MmQtSGlMZi05QSJ9.eYA6tt3fNuUpoxKWDT7P0Lbn2juxhEbTxEnwEMbjlYLLQ3sxL-dYTA.ven-FhmdjlC9itH0.a2jRTarN9vPd6F_mWnNBlOn6KbfMjCApmci2t65XbAsLzYFzhI_79Ykm5ueMYTupWLTjBJctl-g51ZHmsSB55pStbpoyyLNAsUX2E1fTmHe-Ni8bRrspwLv15FoN1Xo1g0mpR-ufWIFxOsW-QIfnMmMIIkygVuHFXmg2tFpzTNNG5aS29K3dN2nyk0WJrdIq79hZSTqVkkBU25Yu3A46sgjcM86XcIJJ2XUEih_KWEa6T1YrkixGu96pebjVqbO0R6dbDckfPF7FqNnwPHVtb1ACFpEYoOJVIbUCMaARBpWsxYhjJZlEM__XA46l8snFQDkNY3CdN0p1_gF3ckA.JLmq9nmu1h9oUi1S8ZxYjA","options":{"x509":{},"ssh":{}}}
|
||||||
|
tls:
|
||||||
|
cipherSuites:
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
minVersion: 1.2
|
||||||
|
maxVersion: 1.3
|
||||||
|
renegotiation: false
|
||||||
|
|
||||||
|
defaults.json:
|
||||||
|
ca-url: https://127.0.0.1
|
||||||
|
ca-config: /home/step/config/ca.json
|
||||||
|
fingerprint: e543cad8e9f6417076bb5aed3471c588152118aac1e0ca7984a43ee7f76da5e3
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
|
||||||
|
# Certificates contains the root and intermediate certificate and
|
||||||
|
# optionally the SSH host and user public keys
|
||||||
|
certificates:
|
||||||
|
# intermediate_ca contains the text of the intermediate CA Certificate
|
||||||
|
intermediate_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBjZXJ0IGJ5
|
||||||
|
dGVz
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca contains the text of the root CA Certificate
|
||||||
|
root_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0EgY2VydCBieXRlcw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# Secrets contains the root and intermediate keys and optionally the SSH
|
||||||
|
# private keys
|
||||||
|
secrets:
|
||||||
|
# ca_password contains the password used to encrypt x509.intermediate_ca_key, ssh.host_ca_key and ssh.user_ca_key
|
||||||
|
# This value must be base64 encoded.
|
||||||
|
ca_password:
|
||||||
|
provisioner_password:
|
||||||
|
|
||||||
|
x509:
|
||||||
|
# intermediate_ca_key contains the contents of your encrypted intermediate CA key
|
||||||
|
intermediate_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBrZXkgYnl0
|
||||||
|
ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca_key contains the contents of your encrypted root CA key
|
||||||
|
# Note that this value can be omitted without impacting the functionality of step-certificates
|
||||||
|
# If supplied, this should be encrypted using a unique password that is not used for encrypting
|
||||||
|
# the intermediate_ca_key, ssh.host_ca_key or ssh.user_ca_key.
|
||||||
|
root_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0Ega2V5IGJ5dGVz
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
81
pki/testdata/helm/with-provisioner.yml
vendored
Normal file
81
pki/testdata/helm/with-provisioner.yml
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# Helm template
|
||||||
|
inject:
|
||||||
|
enabled: true
|
||||||
|
# Config contains the configuration files ca.json and defaults.json
|
||||||
|
config:
|
||||||
|
files:
|
||||||
|
ca.json:
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
federateRoots: []
|
||||||
|
crt: /home/step/certs/intermediate_ca.crt
|
||||||
|
key: /home/step/secrets/intermediate_ca_key
|
||||||
|
address: 127.0.0.1:9000
|
||||||
|
dnsNames:
|
||||||
|
- 127.0.0.1
|
||||||
|
logger:
|
||||||
|
format: json
|
||||||
|
db:
|
||||||
|
type: badgerv2
|
||||||
|
dataSource: /home/step/db
|
||||||
|
authority:
|
||||||
|
enableAdmin: false
|
||||||
|
provisioners:
|
||||||
|
- {"type":"JWK","name":"a-provisioner","key":{"use":"sig","kty":"EC","kid":"zsUmysmDVoGJ71YoPHyZ-68tNihDaDaO5Mu7xX3M-_I","crv":"P-256","alg":"ES256","x":"Pqnua4CzqKz6ua41J3yeWZ1sRkGt0UlCkbHv8H2DGuY","y":"UhoZ_2ItDen9KQTcjay-ph-SBXH0mwqhHyvrrqIFDOI"},"encryptedKey":"eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiZjVvdGVRS2hvOXl4MmQtSGlMZi05QSJ9.eYA6tt3fNuUpoxKWDT7P0Lbn2juxhEbTxEnwEMbjlYLLQ3sxL-dYTA.ven-FhmdjlC9itH0.a2jRTarN9vPd6F_mWnNBlOn6KbfMjCApmci2t65XbAsLzYFzhI_79Ykm5ueMYTupWLTjBJctl-g51ZHmsSB55pStbpoyyLNAsUX2E1fTmHe-Ni8bRrspwLv15FoN1Xo1g0mpR-ufWIFxOsW-QIfnMmMIIkygVuHFXmg2tFpzTNNG5aS29K3dN2nyk0WJrdIq79hZSTqVkkBU25Yu3A46sgjcM86XcIJJ2XUEih_KWEa6T1YrkixGu96pebjVqbO0R6dbDckfPF7FqNnwPHVtb1ACFpEYoOJVIbUCMaARBpWsxYhjJZlEM__XA46l8snFQDkNY3CdN0p1_gF3ckA.JLmq9nmu1h9oUi1S8ZxYjA","options":{"x509":{},"ssh":{}}}
|
||||||
|
tls:
|
||||||
|
cipherSuites:
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
minVersion: 1.2
|
||||||
|
maxVersion: 1.3
|
||||||
|
renegotiation: false
|
||||||
|
|
||||||
|
defaults.json:
|
||||||
|
ca-url: https://127.0.0.1
|
||||||
|
ca-config: /home/step/config/ca.json
|
||||||
|
fingerprint: e543cad8e9f6417076bb5aed3471c588152118aac1e0ca7984a43ee7f76da5e3
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
|
||||||
|
# Certificates contains the root and intermediate certificate and
|
||||||
|
# optionally the SSH host and user public keys
|
||||||
|
certificates:
|
||||||
|
# intermediate_ca contains the text of the intermediate CA Certificate
|
||||||
|
intermediate_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBjZXJ0IGJ5
|
||||||
|
dGVz
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca contains the text of the root CA Certificate
|
||||||
|
root_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0EgY2VydCBieXRlcw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# Secrets contains the root and intermediate keys and optionally the SSH
|
||||||
|
# private keys
|
||||||
|
secrets:
|
||||||
|
# ca_password contains the password used to encrypt x509.intermediate_ca_key, ssh.host_ca_key and ssh.user_ca_key
|
||||||
|
# This value must be base64 encoded.
|
||||||
|
ca_password:
|
||||||
|
provisioner_password:
|
||||||
|
|
||||||
|
x509:
|
||||||
|
# intermediate_ca_key contains the contents of your encrypted intermediate CA key
|
||||||
|
intermediate_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBrZXkgYnl0
|
||||||
|
ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca_key contains the contents of your encrypted root CA key
|
||||||
|
# Note that this value can be omitted without impacting the functionality of step-certificates
|
||||||
|
# If supplied, this should be encrypted using a unique password that is not used for encrypting
|
||||||
|
# the intermediate_ca_key, ssh.host_ca_key or ssh.user_ca_key.
|
||||||
|
root_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0Ega2V5IGJ5dGVz
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
105
pki/testdata/helm/with-ssh-and-acme.yml
vendored
Normal file
105
pki/testdata/helm/with-ssh-and-acme.yml
vendored
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
# Helm template
|
||||||
|
inject:
|
||||||
|
enabled: true
|
||||||
|
# Config contains the configuration files ca.json and defaults.json
|
||||||
|
config:
|
||||||
|
files:
|
||||||
|
ca.json:
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
federateRoots: []
|
||||||
|
crt: /home/step/certs/intermediate_ca.crt
|
||||||
|
key: /home/step/secrets/intermediate_ca_key
|
||||||
|
ssh:
|
||||||
|
hostKey: /home/step/secrets/ssh_host_ca_key
|
||||||
|
userKey: /home/step/secrets/ssh_user_ca_key
|
||||||
|
address: 127.0.0.1:9000
|
||||||
|
dnsNames:
|
||||||
|
- 127.0.0.1
|
||||||
|
logger:
|
||||||
|
format: json
|
||||||
|
db:
|
||||||
|
type: badgerv2
|
||||||
|
dataSource: /home/step/db
|
||||||
|
authority:
|
||||||
|
enableAdmin: false
|
||||||
|
provisioners:
|
||||||
|
- {"type":"JWK","name":"step-cli","key":{"use":"sig","kty":"EC","kid":"zsUmysmDVoGJ71YoPHyZ-68tNihDaDaO5Mu7xX3M-_I","crv":"P-256","alg":"ES256","x":"Pqnua4CzqKz6ua41J3yeWZ1sRkGt0UlCkbHv8H2DGuY","y":"UhoZ_2ItDen9KQTcjay-ph-SBXH0mwqhHyvrrqIFDOI"},"encryptedKey":"eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiZjVvdGVRS2hvOXl4MmQtSGlMZi05QSJ9.eYA6tt3fNuUpoxKWDT7P0Lbn2juxhEbTxEnwEMbjlYLLQ3sxL-dYTA.ven-FhmdjlC9itH0.a2jRTarN9vPd6F_mWnNBlOn6KbfMjCApmci2t65XbAsLzYFzhI_79Ykm5ueMYTupWLTjBJctl-g51ZHmsSB55pStbpoyyLNAsUX2E1fTmHe-Ni8bRrspwLv15FoN1Xo1g0mpR-ufWIFxOsW-QIfnMmMIIkygVuHFXmg2tFpzTNNG5aS29K3dN2nyk0WJrdIq79hZSTqVkkBU25Yu3A46sgjcM86XcIJJ2XUEih_KWEa6T1YrkixGu96pebjVqbO0R6dbDckfPF7FqNnwPHVtb1ACFpEYoOJVIbUCMaARBpWsxYhjJZlEM__XA46l8snFQDkNY3CdN0p1_gF3ckA.JLmq9nmu1h9oUi1S8ZxYjA","claims":{"enableSSHCA":true,"disableRenewal":false,"allowRenewalAfterExpiry":false},"options":{"x509":{},"ssh":{}}}
|
||||||
|
- {"type":"ACME","name":"acme"}
|
||||||
|
- {"type":"SSHPOP","name":"sshpop","claims":{"enableSSHCA":true}}
|
||||||
|
tls:
|
||||||
|
cipherSuites:
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
minVersion: 1.2
|
||||||
|
maxVersion: 1.3
|
||||||
|
renegotiation: false
|
||||||
|
|
||||||
|
defaults.json:
|
||||||
|
ca-url: https://127.0.0.1
|
||||||
|
ca-config: /home/step/config/ca.json
|
||||||
|
fingerprint: e543cad8e9f6417076bb5aed3471c588152118aac1e0ca7984a43ee7f76da5e3
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
|
||||||
|
# Certificates contains the root and intermediate certificate and
|
||||||
|
# optionally the SSH host and user public keys
|
||||||
|
certificates:
|
||||||
|
# intermediate_ca contains the text of the intermediate CA Certificate
|
||||||
|
intermediate_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBjZXJ0IGJ5
|
||||||
|
dGVz
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca contains the text of the root CA Certificate
|
||||||
|
root_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0EgY2VydCBieXRlcw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
# ssh_host_ca contains the text of the public ssh key for the SSH root CA
|
||||||
|
ssh_host_ca: ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ0IdS5sZm6KITBMZLEJD6b5ROVraYHcAOr3feFel8r1Wp4DRPR1oU0W00J/zjNBRBbANlJoYN4x/8WNNVZ49Ms=
|
||||||
|
|
||||||
|
# ssh_user_ca contains the text of the public ssh key for the SSH root CA
|
||||||
|
ssh_user_ca: ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEWA1qUxaGwVNErsvEOGe2d6TvLMF+aiVpuOiIEvpMJ3JeJmecLQctjWqeIbpSvy6/gRa7c82Ge5rLlapYmOChs=
|
||||||
|
|
||||||
|
# Secrets contains the root and intermediate keys and optionally the SSH
|
||||||
|
# private keys
|
||||||
|
secrets:
|
||||||
|
# ca_password contains the password used to encrypt x509.intermediate_ca_key, ssh.host_ca_key and ssh.user_ca_key
|
||||||
|
# This value must be base64 encoded.
|
||||||
|
ca_password:
|
||||||
|
provisioner_password:
|
||||||
|
|
||||||
|
x509:
|
||||||
|
# intermediate_ca_key contains the contents of your encrypted intermediate CA key
|
||||||
|
intermediate_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBrZXkgYnl0
|
||||||
|
ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca_key contains the contents of your encrypted root CA key
|
||||||
|
# Note that this value can be omitted without impacting the functionality of step-certificates
|
||||||
|
# If supplied, this should be encrypted using a unique password that is not used for encrypting
|
||||||
|
# the intermediate_ca_key, ssh.host_ca_key or ssh.user_ca_key.
|
||||||
|
root_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0Ega2V5IGJ5dGVz
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
ssh:
|
||||||
|
# ssh_host_ca_key contains the contents of your encrypted SSH Host CA key
|
||||||
|
host_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
ZmFrZSBzc2ggaG9zdCBrZXkgYnl0ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
|
||||||
|
# ssh_user_ca_key contains the contents of your encrypted SSH User CA key
|
||||||
|
user_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
ZmFrZSBzc2ggdXNlciBrZXkgYnl0ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
104
pki/testdata/helm/with-ssh.yml
vendored
Normal file
104
pki/testdata/helm/with-ssh.yml
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
# Helm template
|
||||||
|
inject:
|
||||||
|
enabled: true
|
||||||
|
# Config contains the configuration files ca.json and defaults.json
|
||||||
|
config:
|
||||||
|
files:
|
||||||
|
ca.json:
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
federateRoots: []
|
||||||
|
crt: /home/step/certs/intermediate_ca.crt
|
||||||
|
key: /home/step/secrets/intermediate_ca_key
|
||||||
|
ssh:
|
||||||
|
hostKey: /home/step/secrets/ssh_host_ca_key
|
||||||
|
userKey: /home/step/secrets/ssh_user_ca_key
|
||||||
|
address: 127.0.0.1:9000
|
||||||
|
dnsNames:
|
||||||
|
- 127.0.0.1
|
||||||
|
logger:
|
||||||
|
format: json
|
||||||
|
db:
|
||||||
|
type: badgerv2
|
||||||
|
dataSource: /home/step/db
|
||||||
|
authority:
|
||||||
|
enableAdmin: false
|
||||||
|
provisioners:
|
||||||
|
- {"type":"JWK","name":"step-cli","key":{"use":"sig","kty":"EC","kid":"zsUmysmDVoGJ71YoPHyZ-68tNihDaDaO5Mu7xX3M-_I","crv":"P-256","alg":"ES256","x":"Pqnua4CzqKz6ua41J3yeWZ1sRkGt0UlCkbHv8H2DGuY","y":"UhoZ_2ItDen9KQTcjay-ph-SBXH0mwqhHyvrrqIFDOI"},"encryptedKey":"eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiZjVvdGVRS2hvOXl4MmQtSGlMZi05QSJ9.eYA6tt3fNuUpoxKWDT7P0Lbn2juxhEbTxEnwEMbjlYLLQ3sxL-dYTA.ven-FhmdjlC9itH0.a2jRTarN9vPd6F_mWnNBlOn6KbfMjCApmci2t65XbAsLzYFzhI_79Ykm5ueMYTupWLTjBJctl-g51ZHmsSB55pStbpoyyLNAsUX2E1fTmHe-Ni8bRrspwLv15FoN1Xo1g0mpR-ufWIFxOsW-QIfnMmMIIkygVuHFXmg2tFpzTNNG5aS29K3dN2nyk0WJrdIq79hZSTqVkkBU25Yu3A46sgjcM86XcIJJ2XUEih_KWEa6T1YrkixGu96pebjVqbO0R6dbDckfPF7FqNnwPHVtb1ACFpEYoOJVIbUCMaARBpWsxYhjJZlEM__XA46l8snFQDkNY3CdN0p1_gF3ckA.JLmq9nmu1h9oUi1S8ZxYjA","claims":{"enableSSHCA":true,"disableRenewal":false,"allowRenewalAfterExpiry":false},"options":{"x509":{},"ssh":{}}}
|
||||||
|
- {"type":"SSHPOP","name":"sshpop","claims":{"enableSSHCA":true}}
|
||||||
|
tls:
|
||||||
|
cipherSuites:
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
minVersion: 1.2
|
||||||
|
maxVersion: 1.3
|
||||||
|
renegotiation: false
|
||||||
|
|
||||||
|
defaults.json:
|
||||||
|
ca-url: https://127.0.0.1
|
||||||
|
ca-config: /home/step/config/ca.json
|
||||||
|
fingerprint: e543cad8e9f6417076bb5aed3471c588152118aac1e0ca7984a43ee7f76da5e3
|
||||||
|
root: /home/step/certs/root_ca.crt
|
||||||
|
|
||||||
|
# Certificates contains the root and intermediate certificate and
|
||||||
|
# optionally the SSH host and user public keys
|
||||||
|
certificates:
|
||||||
|
# intermediate_ca contains the text of the intermediate CA Certificate
|
||||||
|
intermediate_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBjZXJ0IGJ5
|
||||||
|
dGVz
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca contains the text of the root CA Certificate
|
||||||
|
root_ca: |
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0EgY2VydCBieXRlcw==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
|
||||||
|
# ssh_host_ca contains the text of the public ssh key for the SSH root CA
|
||||||
|
ssh_host_ca: ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ0IdS5sZm6KITBMZLEJD6b5ROVraYHcAOr3feFel8r1Wp4DRPR1oU0W00J/zjNBRBbANlJoYN4x/8WNNVZ49Ms=
|
||||||
|
|
||||||
|
# ssh_user_ca contains the text of the public ssh key for the SSH root CA
|
||||||
|
ssh_user_ca: ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEWA1qUxaGwVNErsvEOGe2d6TvLMF+aiVpuOiIEvpMJ3JeJmecLQctjWqeIbpSvy6/gRa7c82Ge5rLlapYmOChs=
|
||||||
|
|
||||||
|
# Secrets contains the root and intermediate keys and optionally the SSH
|
||||||
|
# private keys
|
||||||
|
secrets:
|
||||||
|
# ca_password contains the password used to encrypt x509.intermediate_ca_key, ssh.host_ca_key and ssh.user_ca_key
|
||||||
|
# This value must be base64 encoded.
|
||||||
|
ca_password:
|
||||||
|
provisioner_password:
|
||||||
|
|
||||||
|
x509:
|
||||||
|
# intermediate_ca_key contains the contents of your encrypted intermediate CA key
|
||||||
|
intermediate_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIGludGVybWVkaWF0ZSBDQSBrZXkgYnl0
|
||||||
|
ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
|
||||||
|
# root_ca_key contains the contents of your encrypted root CA key
|
||||||
|
# Note that this value can be omitted without impacting the functionality of step-certificates
|
||||||
|
# If supplied, this should be encrypted using a unique password that is not used for encrypting
|
||||||
|
# the intermediate_ca_key, ssh.host_ca_key or ssh.user_ca_key.
|
||||||
|
root_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
dGhlc2UgYXJlIGp1c3Qgc29tZSBmYWtlIHJvb3QgQ0Ega2V5IGJ5dGVz
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
ssh:
|
||||||
|
# ssh_host_ca_key contains the contents of your encrypted SSH Host CA key
|
||||||
|
host_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
ZmFrZSBzc2ggaG9zdCBrZXkgYnl0ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
||||||
|
|
||||||
|
# ssh_user_ca_key contains the contents of your encrypted SSH User CA key
|
||||||
|
user_ca_key: |
|
||||||
|
-----BEGIN EC PRIVATE KEY-----
|
||||||
|
ZmFrZSBzc2ggdXNlciBrZXkgYnl0ZXM=
|
||||||
|
-----END EC PRIVATE KEY-----
|
||||||
|
|
Loading…
Add table
Reference in a new issue