Skip to content

Commit 1315789

Browse files
Danylo Patsoradpatsora
authored andcommitted
feature: RS256 JWT signature
* feature: First user as superadmin * enhancement: Add Kaigara to the Dockerfile * enhancement: Add .drone.yml w/ Docker build
1 parent 6581728 commit 1315789

37 files changed

+343
-102
lines changed

.drone.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
type: docker
3+
kind: pipeline
4+
name: "Main"
5+
6+
steps:
7+
- name: Docker build Git SHA
8+
image: plugins/docker:20
9+
pull: if-not-exists
10+
environment:
11+
DOCKER_BUILDKIT: 1
12+
settings:
13+
username:
14+
from_secret: quay_username
15+
password:
16+
from_secret: quay_password
17+
repo: quay.io/openware/gotrue
18+
registry: quay.io
19+
tag: ${DRONE_COMMIT:0:7}
20+
purge: false
21+
when:
22+
event:
23+
- push
24+
branch:
25+
- stable/ow
26+
- feature/asymmetric-auth

Dockerfile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ ENV GO111MODULE=on
33
ENV CGO_ENABLED=0
44
ENV GOOS=linux
55

6-
RUN apk add --no-cache make git
6+
RUN apk add --no-cache make git curl
77

88
WORKDIR /go/src/github.com/netlify/gotrue
99

@@ -15,11 +15,16 @@ RUN make deps
1515
COPY . /go/src/github.com/netlify/gotrue
1616
RUN make build
1717

18+
ARG KAIGARA_VERSION=v1.0.10
19+
RUN curl -Lo ./kaigara https://github.com/openware/kaigara/releases/download/${KAIGARA_VERSION}/kaigara \
20+
&& chmod +x ./kaigara
21+
1822
FROM alpine:3.17
1923
RUN adduser -D -u 1000 netlify
2024

2125
RUN apk add --no-cache ca-certificates
2226
COPY --from=build /go/src/github.com/netlify/gotrue/gotrue /usr/local/bin/gotrue
27+
COPY --from=build /go/src/github.com/netlify/gotrue/kaigara /usr/local/bin/kaigara
2328
COPY --from=build /go/src/github.com/netlify/gotrue/migrations /usr/local/etc/gotrue/migrations/
2429

2530
ENV GOTRUE_DB_MIGRATIONS_PATH /usr/local/etc/gotrue/migrations

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,13 +395,17 @@ by default.
395395

396396
```properties
397397
GOTRUE_JWT_SECRET=supersecretvalue
398+
GOTRUE_JWT_ALGORITHM=RS256
398399
GOTRUE_JWT_EXP=3600
399400
GOTRUE_JWT_AUD=netlify
400401
```
402+
`JWT_ALGORITHM` - `string`
403+
404+
The signing algorithm for the JWT. Defaults to HS256.
401405

402406
`JWT_SECRET` - `string` **required**
403407

404-
The secret used to sign JWT tokens with.
408+
The secret used to sign JWT tokens with. If signing alogrithm is RS256, secret has to be Base64 encoded RSA private key.
405409

406410
`JWT_EXP` - `number`
407411

api/admin_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ import (
1111
"time"
1212

1313
jwt "github.com/golang-jwt/jwt"
14-
"github.com/netlify/gotrue/conf"
15-
"github.com/netlify/gotrue/models"
1614
"github.com/stretchr/testify/assert"
1715
"github.com/stretchr/testify/require"
1816
"github.com/stretchr/testify/suite"
17+
18+
"github.com/netlify/gotrue/conf"
19+
"github.com/netlify/gotrue/models"
1920
)
2021

2122
type AdminTestSuite struct {

api/api.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ import (
99
"github.com/didip/tollbooth/v5"
1010
"github.com/didip/tollbooth/v5/limiter"
1111
"github.com/go-chi/chi"
12+
"github.com/sirupsen/logrus"
13+
1214
"github.com/netlify/gotrue/conf"
13-
"github.com/netlify/gotrue/mailer"
14-
"github.com/netlify/gotrue/observability"
1515
"github.com/netlify/gotrue/storage"
16+
1617
"github.com/rs/cors"
1718
"github.com/sebest/xff"
18-
"github.com/sirupsen/logrus"
19+
20+
"github.com/netlify/gotrue/mailer"
21+
"github.com/netlify/gotrue/observability"
1922
)
2023

2124
const (

api/audit_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import (
99
"time"
1010

1111
jwt "github.com/golang-jwt/jwt"
12-
"github.com/netlify/gotrue/conf"
13-
"github.com/netlify/gotrue/models"
1412
"github.com/stretchr/testify/assert"
1513
"github.com/stretchr/testify/require"
1614
"github.com/stretchr/testify/suite"
15+
16+
"github.com/netlify/gotrue/conf"
17+
"github.com/netlify/gotrue/models"
1718
)
1819

1920
type AuditTestSuite struct {
@@ -49,12 +50,12 @@ func (ts *AuditTestSuite) makeSuperAdmin(email string) string {
4950
u.Role = "supabase_admin"
5051

5152
var token string
52-
token, err = generateAccessToken(ts.API.db, u, nil, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.Secret)
53+
token, err = generateAccessToken(ts.API.db, u, nil, time.Second*time.Duration(ts.Config.JWT.Exp), ts.Config.JWT.GetSigningMethod(), ts.Config.JWT.GetSigningKey())
5354
require.NoError(ts.T(), err, "Error generating access token")
5455

5556
p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}}
5657
_, err = p.Parse(token, func(token *jwt.Token) (interface{}, error) {
57-
return []byte(ts.Config.JWT.Secret), nil
58+
return ts.Config.JWT.GetVerificationKey(), nil
5859
})
5960
require.NoError(ts.T(), err, "Error parsing token")
6061

api/auth.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/gofrs/uuid"
1010
jwt "github.com/golang-jwt/jwt"
11+
1112
"github.com/netlify/gotrue/models"
1213
"github.com/netlify/gotrue/storage"
1314
)
@@ -68,9 +69,9 @@ func (a *API) parseJWTClaims(bearer string, r *http.Request) (context.Context, e
6869
ctx := r.Context()
6970
config := a.config
7071

71-
p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}}
72+
p := jwt.Parser{ValidMethods: []string{config.JWT.Algorithm}}
7273
token, err := p.ParseWithClaims(bearer, &GoTrueClaims{}, func(token *jwt.Token) (interface{}, error) {
73-
return []byte(config.JWT.Secret), nil
74+
return config.JWT.GetVerificationKey(), nil
7475
})
7576
if err != nil {
7677
return nil, unauthorizedError("invalid JWT: unable to parse or verify signature, %v", err)

api/external.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func (a *API) ExternalProviderRedirect(w http.ResponseWriter, r *http.Request) e
6565
log := observability.GetLogEntry(r)
6666
log.WithField("provider", providerType).Info("Redirecting to external provider")
6767

68-
token := jwt.NewWithClaims(jwt.SigningMethodHS256, ExternalProviderClaims{
68+
token := jwt.NewWithClaims(config.JWT.GetSigningMethod(), ExternalProviderClaims{
6969
NetlifyMicroserviceClaims: NetlifyMicroserviceClaims{
7070
StandardClaims: jwt.StandardClaims{
7171
ExpiresAt: time.Now().Add(5 * time.Minute).Unix(),
@@ -77,7 +77,7 @@ func (a *API) ExternalProviderRedirect(w http.ResponseWriter, r *http.Request) e
7777
InviteToken: inviteToken,
7878
Referrer: redirectURL,
7979
})
80-
tokenString, err := token.SignedString([]byte(config.JWT.Secret))
80+
tokenString, err := token.SignedString(config.JWT.GetSigningKey())
8181
if err != nil {
8282
return internalServerError("Error creating state").WithInternalError(err)
8383
}
@@ -424,9 +424,9 @@ func (a *API) processInvite(r *http.Request, ctx context.Context, tx *storage.Co
424424
func (a *API) loadExternalState(ctx context.Context, state string) (context.Context, error) {
425425
config := a.config
426426
claims := ExternalProviderClaims{}
427-
p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}}
427+
p := jwt.Parser{ValidMethods: []string{config.JWT.Algorithm}}
428428
_, err := p.ParseWithClaims(state, &claims, func(token *jwt.Token) (interface{}, error) {
429-
return []byte(config.JWT.Secret), nil
429+
return config.JWT.GetVerificationKey(), nil
430430
})
431431
if err != nil || claims.Provider == "" {
432432
return nil, badRequestError("OAuth state is invalid: %v", err)

api/external_apple_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func (ts *ExternalTestSuite) TestSignupExternalApple() {
2424
claims := ExternalProviderClaims{}
2525
p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}}
2626
_, err = p.ParseWithClaims(q.Get("state"), &claims, func(token *jwt.Token) (interface{}, error) {
27-
return []byte(ts.Config.JWT.Secret), nil
27+
return ts.Config.JWT.GetVerificationKey(), nil
2828
})
2929
ts.Require().NoError(err)
3030

api/external_azure_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func (ts *ExternalTestSuite) TestSignupExternalAzure() {
3030
claims := ExternalProviderClaims{}
3131
p := jwt.Parser{ValidMethods: []string{jwt.SigningMethodHS256.Name}}
3232
_, err = p.ParseWithClaims(q.Get("state"), &claims, func(token *jwt.Token) (interface{}, error) {
33-
return []byte(ts.Config.JWT.Secret), nil
33+
return ts.Config.JWT.GetVerificationKey(), nil
3434
})
3535
ts.Require().NoError(err)
3636

0 commit comments

Comments
 (0)