Skip to content

Commit

Permalink
Revert "Remove Server Side Consistent Tokens (SSCTs)"
Browse files Browse the repository at this point in the history
This reverts commit 1f2635c.
As discussed on #openbao-general, this breaks existing migrations:
anyone with SSCT tokens present in token store would lose all
existing tokens and need to re-auth everything. This is moderately
more disruptive for root tokens in particular, as
`operator generate-root` would need to be taken (and sometimes
these root tokens are stored but not used, as they don't necessarily
expire).

This reasonably breaks the "drop-in migration" guarantees of a Raft
storage backend, and thus will be reverted for the time being.

Other than the protobuf regeneration (which makes sense as it is an
auto-generated file anyways), this was a clean revert.

Resolves: #297

Signed-off-by: Alexander Scheel <[email protected]>
  • Loading branch information
cipherboy authored and naphelps committed Jun 12, 2024
1 parent 5ac7393 commit 15c4855
Show file tree
Hide file tree
Showing 30 changed files with 1,164 additions and 417 deletions.
9 changes: 7 additions & 2 deletions command/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import (
"github.com/openbao/openbao/vault"
)

// minTokenLengthExternal is the minimum size of SSC
// tokens we are currently handing out to end users, without any
// namespace information
const minTokenLengthExternal = 91

func testLoginCommand(tb testing.TB) (*cli.MockUi, *LoginCommand) {
tb.Helper()

Expand Down Expand Up @@ -86,7 +91,7 @@ func TestCustomPath(t *testing.T) {
t.Fatal(err)
}

if l, exp := len(storedToken), vault.TokenLength+2; l < exp {
if l, exp := len(storedToken), minTokenLengthExternal+vault.TokenPrefixLength; l < exp {
t.Errorf("expected token to be %d characters, was %d: %q", exp, l, storedToken)
}
}
Expand Down Expand Up @@ -214,7 +219,7 @@ func TestTokenOnly(t *testing.T) {

// Verify only the token was printed
token := ui.OutputWriter.String()
if l, exp := len(token), vault.TokenLength+2; l != exp {
if l, exp := len(token), minTokenLengthExternal+vault.TokenPrefixLength; l != exp {
t.Errorf("expected token to be %d characters, was %d: %q", exp, l, token)
}

Expand Down
1 change: 1 addition & 0 deletions command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2657,6 +2657,7 @@ func createCoreConfig(c *ServerCommand, config *server.Config, backend physical.
SecureRandomReader: secureRandomReader,
EnableResponseHeaderHostname: config.EnableResponseHeaderHostname,
EnableResponseHeaderRaftNodeID: config.EnableResponseHeaderRaftNodeID,
DisableSSCTokens: config.DisableSSCTokens,
AdministrativeNamespacePath: config.AdministrativeNamespacePath,
}

Expand Down
2 changes: 2 additions & 0 deletions command/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ type Config struct {

EnableResponseHeaderRaftNodeID bool `hcl:"-"`
EnableResponseHeaderRaftNodeIDRaw interface{} `hcl:"enable_response_header_raft_node_id"`

DisableSSCTokens bool `hcl:"-"`
}

const (
Expand Down
12 changes: 9 additions & 3 deletions helper/namespace/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,19 @@ func SplitIDFromString(input string) (string, string) {
slashIdx := strings.LastIndex(input, "/")

switch {
case strings.HasPrefix(input, consts.BatchTokenPrefix):
prefix = consts.BatchTokenPrefix
case strings.HasPrefix(input, consts.LegacyBatchTokenPrefix):
prefix = consts.LegacyBatchTokenPrefix
input = input[2:]

case strings.HasPrefix(input, consts.LegacyServiceTokenPrefix):
prefix = consts.LegacyServiceTokenPrefix
input = input[2:]
case strings.HasPrefix(input, consts.BatchTokenPrefix):
prefix = consts.BatchTokenPrefix
input = input[4:]
case strings.HasPrefix(input, consts.ServiceTokenPrefix):
prefix = consts.ServiceTokenPrefix
input = input[2:]
input = input[4:]

case slashIdx > 0:
// Leases will never have a b./s. to start
Expand Down
14 changes: 11 additions & 3 deletions http/sys_generate_root.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,12 @@ func handleSysGenerateRootAttemptGet(core *vault.Core, w http.ResponseWriter, r
respondError(w, http.StatusInternalServerError, err)
return
}

otpLength := vault.TokenLength + vault.TokenPrefixLength
var otpLength int
if core.DisableSSCTokens() {
otpLength = vault.TokenLength + vault.OldTokenPrefixLength
} else {
otpLength = vault.TokenLength + vault.TokenPrefixLength
}

// Format the status
status := &GenerateRootStatusResponse{
Expand Down Expand Up @@ -103,7 +107,11 @@ func handleSysGenerateRootAttemptPut(core *vault.Core, w http.ResponseWriter, r
case len(req.PGPKey) > 0, len(req.OTP) > 0:
default:
genned = true
req.OTP, err = base62.Random(vault.TokenLength + vault.TokenPrefixLength)
if core.DisableSSCTokens() {
req.OTP, err = base62.Random(vault.TokenLength + vault.OldTokenPrefixLength)
} else {
req.OTP, err = base62.Random(vault.TokenLength + vault.TokenPrefixLength)
}
if err != nil {
respondError(w, http.StatusInternalServerError, err)
return
Expand Down
9 changes: 6 additions & 3 deletions sdk/helper/consts/token_consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
package consts

const (
ServiceTokenPrefix = "s."
BatchTokenPrefix = "b."
RecoveryTokenPrefix = "r."
ServiceTokenPrefix = "hvs."
BatchTokenPrefix = "hvb."
RecoveryTokenPrefix = "hvr."
LegacyServiceTokenPrefix = "s."
LegacyBatchTokenPrefix = "b."
LegacyRecoveryTokenPrefix = "r."
)
4 changes: 4 additions & 0 deletions sdk/logical/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ type Request struct {
// client token.
ClientID string `json:"client_id" structs:"client_id" mapstructure:"client_id" sentinel:""`

// InboundSSCToken is the token that arrives on an inbound request, supplied
// by the vault user.
InboundSSCToken string

// When a request has been forwarded, contains information of the host the request was forwarded 'from'
ForwardedFrom string `json:"forwarded_from,omitempty"`
}
Expand Down
4 changes: 4 additions & 0 deletions sdk/logical/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ type TokenEntry struct {
// ID of this entry, generally a random UUID
ID string `json:"id" mapstructure:"id" structs:"id" sentinel:""`

// ExternalID is the ID of a newly created service
// token that will be returned to a user
ExternalID string `json:"-"`

// Accessor for this token, a random UUID
Accessor string `json:"accessor" mapstructure:"accessor" structs:"accessor" sentinel:""`

Expand Down
Loading

0 comments on commit 15c4855

Please sign in to comment.