Files
threshold/internal/server/worker_auth_server_led_activation_token.go
T
Jeff MitchellandIrena Rindos 01fb949d0b Add controller-led worker auth flow (#2413)
This adds an action to the API that allows pulling out an activation
token that can be given to a worker in its config (directly or via env
or file). The worker can pass this along with its normal request in
place of its normal nonce and the server will automatically accept it.

Co-authored-by: Irena Rindos <irenarindos@users.noreply.github.com>
2022-09-02 14:32:41 -04:00

114 lines
4.0 KiB
Go

package server
import (
"context"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/server/store"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
"github.com/hashicorp/go-kms-wrapping/v2/extras/structwrapping"
"google.golang.org/protobuf/proto"
)
// WorkerAuthServerLedActivationToken contains an activation token for a worker
type WorkerAuthServerLedActivationToken struct {
*store.WorkerAuthServerLedActivationToken
tableName string `gorm:"-"`
}
// newWorkerAuthServerLedActivation creates a new token from the given values
func newWorkerAuthServerLedActivationToken(ctx context.Context, workerId, tokenId string, creationTime []byte, _ ...Option) (*WorkerAuthServerLedActivationToken, error) {
const op = "server.newWorkerAuthServerLedActivationToken"
switch {
case workerId == "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "no worker id")
case tokenId == "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "no token id")
case len(creationTime) == 0:
return nil, errors.New(ctx, errors.InvalidParameter, op, "empty creation time")
}
l := &WorkerAuthServerLedActivationToken{
WorkerAuthServerLedActivationToken: &store.WorkerAuthServerLedActivationToken{
WorkerId: workerId,
TokenId: tokenId,
CreationTime: creationTime,
},
}
return l, nil
}
func allocWorkerAuthServerLedActivationToken() *WorkerAuthServerLedActivationToken {
return &WorkerAuthServerLedActivationToken{
WorkerAuthServerLedActivationToken: &store.WorkerAuthServerLedActivationToken{},
}
}
func (w *WorkerAuthServerLedActivationToken) clone() *WorkerAuthServerLedActivationToken {
cp := proto.Clone(w.WorkerAuthServerLedActivationToken)
return &WorkerAuthServerLedActivationToken{
WorkerAuthServerLedActivationToken: cp.(*store.WorkerAuthServerLedActivationToken),
}
}
// ValidateNewWorkerAuthServerLedActivationToken is called before storing a WorkerAuthActivationToken in the db
func (w *WorkerAuthServerLedActivationToken) ValidateNewWorkerAuthServerLedActivationToken(ctx context.Context) error {
const op = "server.(WorkerAuthServerLedActivationToken).ValidateNewWorkerAuthServerLedActivationToken"
if w.WorkerId == "" {
return errors.New(ctx, errors.InvalidParameter, op, "missing worker id")
}
if w.TokenId == "" {
return errors.New(ctx, errors.InvalidParameter, op, "missing token id")
}
if len(w.CreationTimeEncrypted) == 0 {
return errors.New(ctx, errors.InvalidParameter, op, "missing encrypted creation time")
}
return nil
}
// TableName returns the table name.
func (w *WorkerAuthServerLedActivationToken) TableName() string {
if w.tableName != "" {
return w.tableName
}
return "worker_auth_server_led_activation_token"
}
// SetTableName sets the table name.
func (w *WorkerAuthServerLedActivationToken) SetTableName(n string) {
w.tableName = n
}
// encrypt the activation token before storing
func (w *WorkerAuthServerLedActivationToken) encrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "server.(WorkerAuthServerLedActivationToken).encrypt"
if cipher == nil {
return errors.New(ctx, errors.InvalidParameter, op, "missing cipher")
}
if err := structwrapping.WrapStruct(ctx, cipher, w.WorkerAuthServerLedActivationToken); err != nil {
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt))
}
keyId, err := cipher.KeyId(ctx)
if err != nil {
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("failed to read cipher key id"))
}
w.KeyId = keyId
return nil
}
// decrypt the auth method after reading it from the db
func (w *WorkerAuthServerLedActivationToken) decrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "server.(WorkerAuthServerLedActivationToken).decrypt"
if cipher == nil {
return errors.New(ctx, errors.InvalidParameter, op, "missing cipher")
}
if err := structwrapping.UnwrapStruct(ctx, cipher, w.WorkerAuthServerLedActivationToken); err != nil {
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt))
}
return nil
}