Skip to content

Commit

Permalink
feature: Web3 authorization support (#1)
Browse files Browse the repository at this point in the history
* fix (docs): adjust docs to be compatible with authorization via user address

* add (challenger): to sign with Metamask wallet and verify in service

* fix (cli): to have graceful shutdown to catch signals and stop services via context

* fix (jwt): adjust jwt generation to be compatible with address, clean code style

* remove (zkp): redundant ZKP related code

* fix (config): code style, remove zkp config initialization

* update (resources): regenerate with new docs

* update (service): removing ZKP related code, update some code style issues, add support for signature verification and JWT issuing by address

* update (pkg): removing ZKP related staff, add compatibility with JWT by user address

* fix: spelling errors, example config file

* fix (CI/CD): build with skaffold instead of werf build

* update (docs): adding admin authorization

* update (docs): adding admin authorization path

* update (resources): with admin authorization docs

* add: supporting admin authorization
  • Loading branch information
mhrynenko authored Dec 5, 2024
1 parent 3a8ac7a commit 4be7f45
Show file tree
Hide file tree
Showing 64 changed files with 885 additions and 821 deletions.
31 changes: 21 additions & 10 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
on:
workflow_dispatch:
push:
branches:
- 'master'
- 'main'

env:
CI_JOB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
converge:
Expand All @@ -19,13 +26,17 @@ jobs:
# This is where you will update the personal access token to GITHUB_TOKEN
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin

- name: Run echo
run: |
werf version
docker version
echo $GITHUB_REPOSITORY
echo $GITHUB_SHA
- name: Run Build
run: |
. $(werf ci-env github --as-file)
werf export service --tag ghcr.io/$GITHUB_REPOSITORY:$GITHUB_SHA
- name: Cache layers
uses: actions/cache@v3
with:
path: "${{ github.workspace }}/.skaffold/cache"
key: skaffold-${{ hashFiles('**/cache') }}
restore-keys: |
skaffold-
- name: Run Skaffold pipeline as command
uses: hiberbee/github-action-skaffold@latest
id: build
with:
command: build --tag ${{ github.sha }}
repository: ghcr.io/${{ github.repository_owner }}
34 changes: 0 additions & 34 deletions .github/workflows/actions_branch.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
#
# Builds the docs and deploys to GitHub pages
#
# https://github.com/actions/setup-node
# Using https://github.com/marketplace/actions/deploy-to-github-pages
name: Deploy to Github pages

on:
workflow_dispatch:
push:
branches:
- main
- master
- 'master'
- 'main'

jobs:
deploy_pages:
Expand Down
31 changes: 18 additions & 13 deletions .github/workflows/tag.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
on:
workflow_dispatch:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- 'v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+'

env:
CI_JOB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
converge:
name: Converge
Expand All @@ -15,20 +19,21 @@ jobs:
with:
fetch-depth: 0

- name: Install werf
uses: werf/actions/[email protected]

- name: Log in to registry
# This is where you will update the personal access token to GITHUB_TOKEN
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin

- name: Run echo
run: |
werf version
docker version
echo $GITHUB_REPOSITORY
echo $GITHUB_REF_NAME
- name: Run Build
run: |
. $(werf ci-env github --as-file)
werf export service --tag ghcr.io/$GITHUB_REPOSITORY:$GITHUB_REF_NAME
- name: Cache layers
uses: actions/cache@v3
with:
path: "${{ github.workspace }}/.skaffold/cache"
key: skaffold-${{ hashFiles('**/cache') }}
restore-keys: |
skaffold-
- name: Run Skaffold pipeline as command
uses: hiberbee/github-action-skaffold@latest
id: build
with:
command: build --tag ${{ github.ref_name }}
repository: ghcr.io/${{ github.repository_owner }}
20 changes: 14 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
FROM golang:1.20-alpine as buildbase
FROM golang:1.21.0-alpine as buildbase

RUN apk add git build-base
ARG CI_JOB_TOKEN

RUN apk add git build-base ca-certificates
WORKDIR /go/src/github.com/rarimo/web3-auth-svc
COPY vendor .
COPY . .

RUN GOOS=linux go build -o /usr/local/bin/web3-auth-svc /go/src/github.com/rarimo/web3-auth-svc
RUN git config --global url."https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com".insteadOf https://gitlab.com
RUN git config --global url."https://${CI_JOB_TOKEN}@github.com/".insteadOf https://github.com/
RUN go env -w GOPRIVATE=github.com/*,gitlab.com/*

RUN go mod tidy && go mod vendor
RUN CGO_ENABLED=1 GO111MODULE=on GOOS=linux go build -o /usr/local/bin/web3-auth-svc /go/src/github.com/rarimo/web3-auth-svc

FROM alpine:3.9

FROM scratch
COPY --from=alpine:3.9 /bin/sh /bin/sh
COPY --from=alpine:3.9 /usr /usr
COPY --from=alpine:3.9 /lib /lib

COPY --from=buildbase /usr/local/bin/web3-auth-svc /usr/local/bin/web3-auth-svc
RUN apk add --no-cache ca-certificates
COPY --from=buildbase /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

ENTRYPOINT ["web3-auth-svc"]
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
RariMe Auth service designed to authorize users with Iden3 AuthV2 ZK-proofs and issue JWT tokens based on it.
This JWT can be used on other internal or external service to authenticate user for executing endpoints.

Frontend firstly should request Base64-encoded challenge using `v1/authorize/{nullifier}/challenge` request.
Frontend firstly should request Base64-encoded challenge using `v1/authorize/{address}/challenge` request.
Then generate AuthV2 ZK proof with received challenge as decoded big-endian value. Using this proof
execute `v1/authorize` request and receive JWT (refresh and access) tokens in response and also in cookies.

Expand Down Expand Up @@ -53,19 +53,19 @@ How protected endpoints definition looks like:

```go
r.Route("/integrations/your-service", func (r chi.Router) {
r.Route("/v1", func (r chi.Router) {
r.Post("/unprotected", handlers.Unprotected)
r.With(middleware.AuthMiddleware(s.client)).Get("/protected", handlers.Protected)
})
r.Route("/v1", func (r chi.Router) {
r.Post("/unprotected", handlers.Unprotected)
r.With(middleware.AuthMiddleware(s.client)).Get("/protected", handlers.Protected)
})
})
```

Then, use parsed claims in handler to allow users execute business logic:

```go
if !auth.Authenticates([]resources.Claim{claim}, auth.UserGrant("nullifier")) {
ape.RenderErr(w, problems.Unauthorized())
return
if !auth.Authenticates([]resources.Claim{claim}, auth.UserGrant("address")) {
ape.RenderErr(w, problems.Unauthorized())
return
}
```

Expand Down
11 changes: 7 additions & 4 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ listener:
addr: :8000

jwt:
secret_key: 0xbcb14d08dc1472b80f49eaf72f0873ac314a7146083bbf3694df8c3238949f2ec0971427f5509382a2812c700e541e328cd6ec65a1383c3ca435cdf55862dc4b
secret_key: 0x...
access_expiration_time: 12h
refresh_expiration_time: 24h

Expand All @@ -15,6 +15,9 @@ cookies:
secure: true
same_site: 4

verifier:
schema: 12345
enabled: false
auth_verifier:
disabled: true

admin:
disabled: false
password_hash: 0x...
8 changes: 8 additions & 0 deletions docs/spec/components/parameters/pathAddress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
in: path
name: 'address'
required: true
schema:
type: string
example: "0x123...abc"
pattern: '^0x[0-9a-fA-F]{40}$'
description: User address 20 bytes
8 changes: 0 additions & 8 deletions docs/spec/components/parameters/pathNullifier.yaml

This file was deleted.

11 changes: 6 additions & 5 deletions docs/spec/components/schemas/Authorize.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ allOf:
properties:
attributes:
required:
- proof
- signature
type: object
properties:
proof:
type: object
format: json.RawMessage
description: JSON-encoded Query ZK-proof.
signature:
type: string
pattern: '^0x[0-9a-fA-F]{130}$'
example: "0x0bf7b3c454fedc179af06cd02f62fb3d89b2ac16962d50137330ffeebe9fac5f6bb2d1f2a971834a8eb84ce0a28894578286812a1131cfe7921b2d325d0b06041c"
description: Backend-generated challenge, signed by user
16 changes: 16 additions & 0 deletions docs/spec/components/schemas/AuthorizeAdmin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
allOf:
- $ref: '#/components/schemas/AuthorizeKey'
- type: object
x-go-is-request: true
required:
- attributes
properties:
attributes:
required:
- password
type: object
properties:
password:
type: string
example: whoami
description: Password to get admin permissions
6 changes: 3 additions & 3 deletions docs/spec/components/schemas/AuthorizeKey.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ required:
properties:
id:
type: string
example: "0x123...abc"
pattern: '^0x[0-9a-fA-F]{64}$'
description: User nullifier 32 bytes
pattern: '^0x[0-9a-fA-F]{40}$'
example: "0x2a2288cdceEeb2CF60..."
description: Address that corresponds to users keypair
type:
type: string
enum: [ authorize ]
6 changes: 2 additions & 4 deletions docs/spec/components/schemas/Challenge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,5 @@ allOf:
properties:
challenge:
type: string
description: |
Base64 encoded challenge. Use it to generate Query ZK-proof.
Decode base64 string and convert into big-endian decimal number.
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
description: Random hex strings challenge which must be signed by user to authorize
example: abcdef...123456
4 changes: 2 additions & 2 deletions docs/spec/components/schemas/ChallengeKey.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ properties:
id:
type: string
example: "0x123...abc"
pattern: '^0x[0-9a-fA-F]{64}$'
description: User nullifier 32 bytes
pattern: '^0x[0-9a-fA-F]{40}$'
description: User address
type:
type: string
enum: [ challenge ]
13 changes: 9 additions & 4 deletions docs/spec/components/schemas/Claim.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
description: 'Authorized user personal data'
type: object
required:
- nullifier
- address
- is_admin
properties:
nullifier:
address:
type: string
example: "0x123...abc"
pattern: '^0x[0-9a-fA-F]{64}$'
description: Nullifier authorized with
pattern: '^0x[0-9a-fA-F]{40}$'
description: Address authorized with
is_admin:
type: bool
example: false
description: Whether the user has a admin permissions
2 changes: 1 addition & 1 deletion docs/spec/components/schemas/TokenKey.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ properties:
type: string
example: "0x123...abc"
pattern: '^0x[0-9a-fA-F]{64}$'
description: User nullifier 32 bytes
description: User address string
type:
type: string
enum: [ token ]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
allOf:
- $ref: '#/components/schemas/ValidationResultKey'
- $ref: '#/components/schemas/ValidationKey'
- type: object
required:
- attributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ properties:
id:
type: string
example: "0x123...abc"
pattern: '^0x[0-9a-fA-F]{64}$'
description: User nullifier 32 bytes
pattern: '^0x[0-9a-fA-F]{40}$'
description: User address
type:
type: string
enum: [ validation ]
Loading

0 comments on commit 4be7f45

Please sign in to comment.