-
Notifications
You must be signed in to change notification settings - Fork 1
[137] Custom Backend JWT Issuer #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 8 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
7f12ad3
feat: custom issuer
GuillemGarciaDev 54ff0a1
fix(custom-issuer): package
GuillemGarciaDev 3002cf3
fix: remove testing keys
GuillemGarciaDev ded2050
fix: add keys folder to gitignore
GuillemGarciaDev 07c82eb
fix(custom-issuer): validate issuer url and key base64
GuillemGarciaDev 363338a
feat: add gha actions for pr and deployment
AdriaCarrera 3a27aa8
Merge remote-tracking branch 'origin/apps/custom-issuer' into apps/cu…
AdriaCarrera 11b5c26
fix: lint
AdriaCarrera aae0e62
fix: keybase64 value in staging
AdriaCarrera File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| name: "Build custom-issuer image" | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| push: | ||
| required: true | ||
| type: boolean | ||
| target: | ||
| required: true | ||
| type: string | ||
| base_image: | ||
| required: true | ||
| type: string | ||
|
|
||
| jobs: | ||
| build: | ||
| name: Build | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| steps: | ||
| # Checkout repository under $GITHUB_WORKSPACE path | ||
| - name: Repository checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Set up QEMU | ||
| uses: docker/setup-qemu-action@v3 | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
|
|
||
| - name: Login to DockerHub | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| username: ${{ secrets.DOCKER_USERNAME }} | ||
| password: ${{ secrets.DOCKER_PUSH_TOKEN }} | ||
|
|
||
| # Configure tag name | ||
| - name: Sets env vars | ||
| run: | | ||
| echo "DOCKER_IMAGE_NAME=${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }}-custom-issuer:${GITHUB_SHA:0:8}" >> $GITHUB_ENV | ||
|
|
||
| # Build docker image | ||
| - name: Build docker image | ||
| uses: docker/build-push-action@v4 | ||
| with: | ||
| context: . | ||
| file: docker/custom-issuer.Dockerfile | ||
| target: ${{ inputs.target }} | ||
| push: ${{ inputs.push }} | ||
| tags: ${{ env.DOCKER_IMAGE_NAME }} | ||
| build-args: | | ||
| BASE_IMAGE=${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }}-base:${{ inputs.base_image }} | ||
| TURBO_TEAM=peersyst | ||
| secrets: | | ||
| turbo_token=${{ secrets.TURBO_TOKEN }} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Custom Issuer Service Environment Variables | ||
| # Copy this file to .env and update with your actual values | ||
|
|
||
| # ============================================================================= | ||
| # REQUIRED - Application will not start without these | ||
| # ============================================================================= | ||
|
|
||
| # Base64-encoded RSA private key used for signing issued tokens | ||
| # To encode a key file: cat signing-key.pem | base64 | ||
| # Example: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVB... | ||
| KEY_BASE64= | ||
|
|
||
| # Firebase URL where the validation public key can be retrieved | ||
| # Firebase certificate format: https://www.googleapis.com/robot/v1/metadata/x509/{service-account-email} | ||
| # Example: https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk@project.iam.gserviceaccount.com | ||
| VALIDATION_PUBLIC_KEY_URL= | ||
|
|
||
| # Expected issuer URL that incoming JWTs must have in their 'iss' claim | ||
| # This should match the issuer URL of the tokens you want to accept | ||
| # Example: https://securetoken.google.com/{project-id} | ||
| VALIDATION_ISSUER_URL= | ||
|
|
||
| # URL of the issuer service (will be included as 'iss' claim in issued tokens) | ||
| # Example: http://localhost:3000 | ||
| ISSUER_URL= | ||
|
|
||
| # ============================================================================= | ||
| # OPTIONAL - Application will use defaults if not set | ||
| # ============================================================================= | ||
|
|
||
| # Port number for the HTTP server (default: 3000) | ||
| PORT=3000 | ||
|
|
||
| # Comma-separated list of allowed CORS origins | ||
| # If not set, CORS will be disabled (no cross-origin requests allowed) | ||
| # Example: http://localhost:3000,https://example.com,https://app.example.com | ||
| ALLOWED_ORIGINS= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| module.exports = { | ||
| root: true, | ||
| extends: [require.resolve("@shared/eslint/nest")], | ||
| rules: { | ||
| "jsdoc/require-jsdoc": "off", | ||
| "jsdoc/require-param": "off", | ||
| "jsdoc/require-returns": "off", | ||
| "jsdoc/match-description": "off", | ||
| "no-console": "off", | ||
| }, | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # compiled output | ||
| /dist | ||
| /node_modules | ||
| /build | ||
|
|
||
| # Logs | ||
| logs | ||
| *.log | ||
| npm-debug.log* | ||
| pnpm-debug.log* | ||
| yarn-debug.log* | ||
| yarn-error.log* | ||
| lerna-debug.log* | ||
|
|
||
| # OS | ||
| .DS_Store | ||
|
|
||
| # Tests | ||
| /coverage | ||
| /.nyc_output | ||
|
|
||
| # IDEs and editors | ||
| /.idea | ||
| .project | ||
| .classpath | ||
| .c9/ | ||
| *.launch | ||
| .settings/ | ||
| *.sublime-workspace | ||
|
|
||
| # IDE - VSCode | ||
| .vscode/* | ||
| !.vscode/settings.json | ||
| !.vscode/tasks.json | ||
| !.vscode/launch.json | ||
| !.vscode/extensions.json | ||
|
|
||
| # dotenv environment variable files | ||
| .env | ||
| .env.development.local | ||
| .env.test.local | ||
| .env.production.local | ||
| .env.local | ||
|
|
||
| # temp directory | ||
| .temp | ||
| .tmp | ||
|
|
||
| # Runtime data | ||
| pids | ||
| *.pid | ||
| *.seed | ||
| *.pid.lock | ||
|
|
||
| # Diagnostic reports (https://nodejs.org/api/report.html) | ||
| report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
|
||
| # Keys | ||
| keys/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| # Custom Issuer Service | ||
|
|
||
| A NestJS service that validates incoming JWTs and issues new tokens with a different signing key. | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ### 1. Install Dependencies | ||
|
|
||
| ```bash | ||
| pnpm install | ||
| ``` | ||
|
|
||
| ### 2. Generate Test Keys (Optional) | ||
|
|
||
| ```bash | ||
| # Generate RSA key pair for testing | ||
| mkdir -p keys | ||
| openssl genrsa -out keys/signing-key.pem 2048 | ||
| openssl rsa -in keys/signing-key.pem -pubout -out keys/validation-public-key.pem | ||
| chmod 600 keys/signing-key.pem | ||
| chmod 644 keys/validation-public-key.pem | ||
| ``` | ||
|
|
||
| ### 3. Configure Environment Variables | ||
|
|
||
| Copy `.env.example` to `.env` and fill in the required values: | ||
|
|
||
| ```bash | ||
| cp .env.example .env | ||
| ``` | ||
|
|
||
| Required variables: | ||
| - `KEY_BASE64` - Base64-encoded RSA private key for signing tokens (encode with: `cat signing-key.pem | base64`) | ||
| - `VALIDATION_PUBLIC_KEY_URL` - Firebase URL where the validation public key can be retrieved (e.g., `https://www.googleapis.com/robot/v1/metadata/x509/{service-account-email}`) | ||
| - `VALIDATION_ISSUER_URL` - Expected issuer URL that incoming JWTs must have in their `iss` claim (e.g., `https://securetoken.google.com/{project-id}`) | ||
| - `ISSUER_URL` - URL of the issuer service (e.g., `http://localhost:3000`) | ||
|
|
||
| Optional variables: | ||
| - `PORT` - Server port (default: 3000) | ||
| - `ALLOWED_ORIGINS` - Comma-separated CORS origins | ||
|
|
||
| ### 4. Start the Service | ||
|
|
||
| ```bash | ||
| # Development mode (with hot reload) | ||
| pnpm start:dev | ||
|
|
||
| # Production mode | ||
| pnpm build | ||
| pnpm start:prod | ||
| ``` | ||
|
|
||
| The service will be available at `http://localhost:3000` (or your configured port). | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Issue a Token | ||
|
|
||
| ```bash | ||
| POST /issuer/issue | ||
| Content-Type: application/json | ||
|
|
||
| { | ||
| "jwt": "your-validated-jwt-token" | ||
| } | ||
| ``` | ||
|
|
||
| The service will: | ||
| 1. Validate the input JWT using the validation public key | ||
| 2. Extract `sub`, `exp`, and `nbf` claims | ||
| 3. Issue a new token signed with the signing private key | ||
| 4. Include the `iss` claim with the issuer URL | ||
|
|
||
| ### Generate Test JWTs | ||
|
|
||
| ```bash | ||
| # Generate and send a test JWT to the service | ||
| pnpm generate:jwt | ||
|
|
||
| # Generate with custom options | ||
| pnpm generate:jwt -- --sub "user@example.com" --exp 7200 | ||
| ``` | ||
|
|
||
| ## Scripts | ||
|
|
||
| - `pnpm start:dev` - Start in development mode with hot reload | ||
| - `pnpm build` - Build for production | ||
| - `pnpm start:prod` - Start production server | ||
| - `pnpm test` - Run tests | ||
| - `pnpm generate:jwt` - Generate test JWT tokens | ||
|
|
||
| ## Security | ||
|
|
||
| - Input validation with `class-validator` | ||
| - Request size limits (10KB) | ||
| - CORS protection | ||
| - Path traversal protection for key files | ||
| - Sensitive data redaction in error logs | ||
| - Rate limiting recommended for production |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "$schema": "https://json.schemastore.org/nest-cli", | ||
| "collection": "@nestjs/schematics", | ||
| "sourceRoot": "src", | ||
| "compilerOptions": { | ||
| "deleteOutDir": true | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
docker/build-push-action latest version releases GitHub Actions💡 Result:
Latest stable major release: v6. Latest published package version: v6.18.0 (current latest). [1][2]
Sources:
Update
docker/build-push-actionto v6.The
docker/build-push-action@v4is outdated. Update to v6.18.0 (the latest stable version).♻️ Proposed update
📝 Committable suggestion
🧰 Tools
🪛 actionlint (1.7.10)
47-47: the runner of "docker/build-push-action@v4" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
🤖 Prompt for AI Agents