Skip to content

Commit

Permalink
Do not fail if a provisioner cannot be initialized
Browse files Browse the repository at this point in the history
This commit will mark a provisioner as disabled if it fails to
initialize. The provisioner will be visible, but authorizing a token
with a disabled provisioner will always fail.

Fixes: #589, #1757
  • Loading branch information
maraino committed Mar 13, 2024
1 parent fe364d5 commit 976bf0c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
5 changes: 4 additions & 1 deletion authority/authority.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,10 @@ func (a *Authority) ReloadAdminResources(ctx context.Context) error {
provClxn := provisioner.NewCollection(provisionerConfig.Audiences)
for _, p := range provList {
if err := p.Init(provisionerConfig); err != nil {
return err
log.Printf("failed to initialize %s provisioner %q: %v\n", p.GetType(), p.GetName(), err)
p = provisioner.Disabled{
Interface: p, Reason: err,
}
}
if err := provClxn.Store(p); err != nil {
return err
Expand Down
4 changes: 4 additions & 0 deletions authority/authorize.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ func (a *Authority) getProvisionerFromToken(token string) (provisioner.Interface
if !ok {
return nil, nil, fmt.Errorf("provisioner not found or invalid audience (%s)", strings.Join(claims.Audience, ", "))
}
// If the provisioner is disabled, send an appropriate message to the client
if _, ok := p.(provisioner.Disabled); ok {
return nil, nil, errs.New(http.StatusUnauthorized, "provisioner %q is disabled due to an initialization error", p.GetName())
}

return p, &claims, nil
}
Expand Down
25 changes: 25 additions & 0 deletions authority/provisioner/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,31 @@ type Interface interface {
AuthorizeSSHRekey(ctx context.Context, token string) (*ssh.Certificate, []SignOption, error)
}

// Disabled represents a disabled provisioner. Disabled provisioners are created
// when the Init methods fails.
type Disabled struct {
Interface
Reason error
}

// MarshalJSON returns the JSON encoding of the provisioner with the disabled
// reason.
func (p Disabled) MarshalJSON() ([]byte, error) {
provisionerJSON, err := json.Marshal(p.Interface)
if err != nil {
return nil, err
}
reasonJSON, err := json.Marshal(struct {
Disabled bool `json:"disabled"`
DisabledReason string `json:"disabledReason"`
}{true, p.Reason.Error()})
if err != nil {
return nil, err
}
reasonJSON[0] = ','
return append(provisionerJSON[:len(provisionerJSON)-1], reasonJSON...), nil
}

// ErrAllowTokenReuse is an error that is returned by provisioners that allows
// the reuse of tokens.
//
Expand Down

0 comments on commit 976bf0c

Please sign in to comment.