Skip to content

Commit

Permalink
cliccl: Add global --enterprise-require-fips-ready flag
Browse files Browse the repository at this point in the history
Previously, misconfigurations of the FIPS environment would result in a
silent fallback to non-FIPS-compliant Go cryptography. This flag permits
users who require FIPS compliance to add some checks to CockroachDB
startup to ensure that the Go crypto implementation will not be used.

Updates #114344

Release note (cli change): New flag --enterprise-require-fips-ready
can be added to any CRDB command to prevent startup if certain
prerequisites for FIPS compliance are not met.
  • Loading branch information
bdarnell committed Nov 27, 2023
1 parent cd9077c commit 9d6d754
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pkg/ccl/cliccl/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ go_library(
"//pkg/ccl/utilccl",
"//pkg/ccl/workloadccl/cliccl",
"//pkg/cli",
"//pkg/cli/clierror",
"//pkg/cli/clierrorplus",
"//pkg/cli/cliflagcfg",
"//pkg/cli/cliflags",
"//pkg/cli/democluster",
"//pkg/cli/exit",
"//pkg/storage",
"//pkg/storage/enginepb",
"//pkg/util/log",
Expand All @@ -44,6 +46,7 @@ go_library(
"@com_github_cockroachdb_redact//:redact",
"@com_github_olekukonko_tablewriter//:tablewriter",
"@com_github_spf13_cobra//:cobra",
"@com_github_spf13_pflag//:pflag",
],
)

Expand Down
56 changes: 56 additions & 0 deletions pkg/ccl/cliccl/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,59 @@
package cliccl

import (
"os"
"strconv"

"github.com/cockroachdb/cockroach/pkg/ccl/securityccl/fipsccl"
"github.com/cockroachdb/cockroach/pkg/cli"
"github.com/cockroachdb/cockroach/pkg/cli/clierror"
"github.com/cockroachdb/cockroach/pkg/cli/cliflagcfg"
"github.com/cockroachdb/cockroach/pkg/cli/cliflags"
"github.com/cockroachdb/cockroach/pkg/cli/exit"
"github.com/cockroachdb/errors"
"github.com/spf13/pflag"
)

type requireFipsFlag bool

// Type implements the pflag.Value interface.
func (f *requireFipsFlag) Type() string {
return "bool"
}

// String implements the pflag.Value interface.
func (f *requireFipsFlag) String() string {
return strconv.FormatBool(bool(*f))
}

// Set implements the pflag.Value interface.
func (f *requireFipsFlag) Set(s string) error {
v, err := strconv.ParseBool(s)
if err != nil {
return err
}
// We implement the logic of this check in the flag setter itself because it
// applies to all commands and we do not have another good way to inject
// this behavior globally (PersistentPreRun functions don't help because
// they are inherited across different levels of the command hierarchy only
// if that level does not have its own hook).
if v && !fipsccl.IsFIPSReady() {
err := errors.WithHint(errors.New("FIPS readiness checks failed"), "Run `cockroach debug enterprise-check-fips` for details")
clierror.OutputError(os.Stderr, err, true, false)
exit.WithCode(exit.UnspecifiedError())
}
*f = requireFipsFlag(v)
return nil
}

var _ pflag.Value = (*requireFipsFlag)(nil)

// IsBoolFlag implements a non-public pflag interface to indicate that this
// flag is used without an explicit value.
func (*requireFipsFlag) IsBoolFlag() bool {
return true
}

func init() {
// Multi-tenancy proxy command flags.
{
Expand Down Expand Up @@ -44,4 +92,12 @@ func init() {
// Use StringFlagDepth to avoid conflicting with the already registered KVAddrs env var.
cliflagcfg.StringFlagDepth(1, f, &testDirectorySvrContext.kvAddrs, cliflags.KVAddrs)
})

// FIPS verification flags.
cli.RegisterFlags(func() {
cmd := cli.CockroachCmd()
var requireFips = requireFipsFlag(false)
flag := cmd.PersistentFlags().VarPF(&requireFips, "enterprise-require-fips-ready", "", "abort if FIPS readiness checks fail")
flag.NoOptDefVal = "true"
})
}
5 changes: 5 additions & 0 deletions pkg/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ var cockroachCmd = &cobra.Command{
},
}

// CockroachCmd returns the root cockroach Command object.
func CockroachCmd() *cobra.Command {
return cockroachCmd
}

var workloadCmd = workloadcli.WorkloadCmd(true /* userFacing */)

func init() {
Expand Down

0 comments on commit 9d6d754

Please sign in to comment.