Skip to content

Commit 6aaa09e

Browse files
committed
chore: shorten provisioner key
1 parent 10b09ed commit 6aaa09e

File tree

10 files changed

+90
-28
lines changed

10 files changed

+90
-28
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,6 +1680,10 @@ func (q *querier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt
16801680
return q.db.GetProvisionerJobsCreatedAfter(ctx, createdAt)
16811681
}
16821682

1683+
func (q *querier) GetProvisionerKeyByHashedSecret(ctx context.Context, hashedSecret []byte) (database.ProvisionerKey, error) {
1684+
return fetch(q.log, q.auth, q.db.GetProvisionerKeyByHashedSecret)(ctx, hashedSecret)
1685+
}
1686+
16831687
func (q *querier) GetProvisionerKeyByID(ctx context.Context, id uuid.UUID) (database.ProvisionerKey, error) {
16841688
return fetch(q.log, q.auth, q.db.GetProvisionerKeyByID)(ctx, id)
16851689
}

coderd/database/dbmem/dbmem.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3240,6 +3240,19 @@ func (q *FakeQuerier) GetProvisionerJobsCreatedAfter(_ context.Context, after ti
32403240
return jobs, nil
32413241
}
32423242

3243+
func (q *FakeQuerier) GetProvisionerKeyByHashedSecret(ctx context.Context, hashedSecret []byte) (database.ProvisionerKey, error) {
3244+
q.mutex.RLock()
3245+
defer q.mutex.RUnlock()
3246+
3247+
for _, key := range q.provisionerKeys {
3248+
if bytes.Equal(key.HashedSecret, hashedSecret) {
3249+
return key, nil
3250+
}
3251+
}
3252+
3253+
return database.ProvisionerKey{}, sql.ErrNoRows
3254+
}
3255+
32433256
func (q *FakeQuerier) GetProvisionerKeyByID(_ context.Context, id uuid.UUID) (database.ProvisionerKey, error) {
32443257
q.mutex.RLock()
32453258
defer q.mutex.RUnlock()

coderd/database/dbmetrics/dbmetrics.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/provisionerkeys.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ FROM
1919
WHERE
2020
id = $1;
2121

22+
-- name: GetProvisionerKeyByHashedSecret :one
23+
SELECT
24+
*
25+
FROM
26+
provisioner_keys
27+
WHERE
28+
hashed_secret = $1;
29+
2230
-- name: GetProvisionerKeyByName :one
2331
SELECT
2432
*

coderd/httpmw/provisionerdaemon.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,17 @@ func ExtractProvisionerDaemonAuthenticated(opts ExtractProvisionerAuthConfig) fu
7171
return
7272
}
7373

74-
id, keyValue, err := provisionerkey.Parse(key)
74+
err := provisionerkey.Validate(key)
7575
if err != nil {
76-
handleOptional(http.StatusUnauthorized, codersdk.Response{
76+
handleOptional(http.StatusBadGateway, codersdk.Response{
7777
Message: "provisioner daemon key invalid",
78+
Detail: err.Error(),
7879
})
7980
return
8081
}
81-
82+
hashedKey := provisionerkey.HashSecret(key)
8283
// nolint:gocritic // System must check if the provisioner key is valid.
83-
pk, err := opts.DB.GetProvisionerKeyByID(dbauthz.AsSystemRestricted(ctx), id)
84+
pk, err := opts.DB.GetProvisionerKeyByHashedSecret(dbauthz.AsSystemRestricted(ctx), hashedKey)
8485
if err != nil {
8586
if httpapi.Is404Error(err) {
8687
handleOptional(http.StatusUnauthorized, codersdk.Response{
@@ -90,12 +91,13 @@ func ExtractProvisionerDaemonAuthenticated(opts ExtractProvisionerAuthConfig) fu
9091
}
9192

9293
handleOptional(http.StatusInternalServerError, codersdk.Response{
93-
Message: "get provisioner daemon key: " + err.Error(),
94+
Message: "get provisioner daemon key",
95+
Detail: err.Error(),
9496
})
9597
return
9698
}
9799

98-
if provisionerkey.Compare(pk.HashedSecret, provisionerkey.HashSecret(keyValue)) {
100+
if provisionerkey.Compare(pk.HashedSecret, hashedKey) {
99101
handleOptional(http.StatusUnauthorized, codersdk.Response{
100102
Message: "provisioner daemon key invalid",
101103
})

coderd/provisionerkey/provisionerkey.go

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package provisionerkey
33
import (
44
"crypto/sha256"
55
"crypto/subtle"
6-
"fmt"
7-
"strings"
86

97
"github.com/google/uuid"
108
"golang.org/x/xerrors"
@@ -15,40 +13,31 @@ import (
1513
)
1614

1715
func New(organizationID uuid.UUID, name string, tags map[string]string) (database.InsertProvisionerKeyParams, string, error) {
18-
id := uuid.New()
19-
secret, err := cryptorand.HexString(64)
16+
secret, err := cryptorand.String(64)
2017
if err != nil {
21-
return database.InsertProvisionerKeyParams{}, "", xerrors.Errorf("generate token: %w", err)
18+
return database.InsertProvisionerKeyParams{}, "", xerrors.Errorf("generate secret: %w", err)
2219
}
23-
hashedSecret := HashSecret(secret)
24-
token := fmt.Sprintf("%s:%s", id, secret)
2520

2621
if tags == nil {
2722
tags = map[string]string{}
2823
}
2924

3025
return database.InsertProvisionerKeyParams{
31-
ID: id,
26+
ID: uuid.New(),
3227
CreatedAt: dbtime.Now(),
3328
OrganizationID: organizationID,
3429
Name: name,
35-
HashedSecret: hashedSecret,
30+
HashedSecret: HashSecret(secret),
3631
Tags: tags,
37-
}, token, nil
32+
}, secret, nil
3833
}
3934

40-
func Parse(token string) (uuid.UUID, string, error) {
41-
parts := strings.Split(token, ":")
42-
if len(parts) != 2 {
43-
return uuid.UUID{}, "", xerrors.Errorf("invalid token format")
35+
func Validate(token string) error {
36+
if len(token) != 64 {
37+
return xerrors.Errorf("must be 64 characters")
4438
}
4539

46-
id, err := uuid.Parse(parts[0])
47-
if err != nil {
48-
return uuid.UUID{}, "", xerrors.Errorf("parse id: %w", err)
49-
}
50-
51-
return id, parts[1], nil
40+
return nil
5241
}
5342

5443
func HashSecret(secret string) []byte {

enterprise/cli/provisionerdaemonstart.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ func (r *RootCmd) provisionerDaemonStart() *serpent.Command {
122122
if len(rawTags) > 0 {
123123
return xerrors.New("cannot provide tags when using provisioner key")
124124
}
125-
_, _, err := provisionerkey.Parse(provisionerKey)
125+
err = provisionerkey.Validate(provisionerKey)
126126
if err != nil {
127-
return xerrors.Errorf("parse provisioner key: %w", err)
127+
return xerrors.Errorf("validate provisioner key: %w", err)
128128
}
129129
}
130130

0 commit comments

Comments
 (0)