mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 09:08:32 +02:00
Add AWS authentication
This commit is contained in:
41
package-lock.json
generated
41
package-lock.json
generated
@@ -8,16 +8,17 @@
|
|||||||
"name": "yaak-app",
|
"name": "yaak-app",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
"packages/common-lib",
|
||||||
"packages/plugin-runtime",
|
"packages/plugin-runtime",
|
||||||
"packages/plugin-runtime-types",
|
"packages/plugin-runtime-types",
|
||||||
"packages/common-lib",
|
"plugins/action-copy-curl",
|
||||||
|
"plugins/action-copy-grpcurl",
|
||||||
"plugins/auth-apikey",
|
"plugins/auth-apikey",
|
||||||
|
"plugins/auth-aws",
|
||||||
"plugins/auth-basic",
|
"plugins/auth-basic",
|
||||||
"plugins/auth-bearer",
|
"plugins/auth-bearer",
|
||||||
"plugins/auth-jwt",
|
"plugins/auth-jwt",
|
||||||
"plugins/auth-oauth2",
|
"plugins/auth-oauth2",
|
||||||
"plugins/action-copy-curl",
|
|
||||||
"plugins/action-copy-grpcurl",
|
|
||||||
"plugins/filter-jsonpath",
|
"plugins/filter-jsonpath",
|
||||||
"plugins/filter-xpath",
|
"plugins/filter-xpath",
|
||||||
"plugins/importer-curl",
|
"plugins/importer-curl",
|
||||||
@@ -26,7 +27,6 @@
|
|||||||
"plugins/importer-postman",
|
"plugins/importer-postman",
|
||||||
"plugins/importer-yaak",
|
"plugins/importer-yaak",
|
||||||
"plugins/template-function-cookie",
|
"plugins/template-function-cookie",
|
||||||
"plugins/template-function-timestamp",
|
|
||||||
"plugins/template-function-encode",
|
"plugins/template-function-encode",
|
||||||
"plugins/template-function-fs",
|
"plugins/template-function-fs",
|
||||||
"plugins/template-function-hash",
|
"plugins/template-function-hash",
|
||||||
@@ -35,13 +35,14 @@
|
|||||||
"plugins/template-function-regex",
|
"plugins/template-function-regex",
|
||||||
"plugins/template-function-request",
|
"plugins/template-function-request",
|
||||||
"plugins/template-function-response",
|
"plugins/template-function-response",
|
||||||
|
"plugins/template-function-timestamp",
|
||||||
"plugins/template-function-uuid",
|
"plugins/template-function-uuid",
|
||||||
"plugins/template-function-xml",
|
"plugins/template-function-xml",
|
||||||
"plugins/themes-yaak",
|
"plugins/themes-yaak",
|
||||||
"src-tauri",
|
"src-tauri",
|
||||||
"src-tauri/yaak-crypto",
|
"src-tauri/yaak-crypto",
|
||||||
"src-tauri/yaak-git",
|
|
||||||
"src-tauri/yaak-fonts",
|
"src-tauri/yaak-fonts",
|
||||||
|
"src-tauri/yaak-git",
|
||||||
"src-tauri/yaak-license",
|
"src-tauri/yaak-license",
|
||||||
"src-tauri/yaak-mac-window",
|
"src-tauri/yaak-mac-window",
|
||||||
"src-tauri/yaak-models",
|
"src-tauri/yaak-models",
|
||||||
@@ -3377,6 +3378,16 @@
|
|||||||
"@tauri-apps/api": "^2.8.0"
|
"@tauri-apps/api": "^2.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/aws4": {
|
||||||
|
"version": "1.11.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/aws4/-/aws4-1.11.6.tgz",
|
||||||
|
"integrity": "sha512-5CnVUkHNyLGpD9AnOcK66YyP0qvIh6nhJJoeK8zSl5YKikUcUbdB7SlHevUYVqicgeh6j5AJa1qa/h08dSZHoA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/babel__core": {
|
"node_modules/@types/babel__core": {
|
||||||
"version": "7.20.5",
|
"version": "7.20.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||||
@@ -4112,6 +4123,10 @@
|
|||||||
"resolved": "plugins/auth-apikey",
|
"resolved": "plugins/auth-apikey",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@yaak/auth-aws": {
|
||||||
|
"resolved": "plugins/auth-aws",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/@yaak/auth-basic": {
|
"node_modules/@yaak/auth-basic": {
|
||||||
"resolved": "plugins/auth-basic",
|
"resolved": "plugins/auth-basic",
|
||||||
"link": true
|
"link": true
|
||||||
@@ -4887,6 +4902,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/aws4": {
|
||||||
|
"version": "1.13.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz",
|
||||||
|
"integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/axe-core": {
|
"node_modules/axe-core": {
|
||||||
"version": "4.10.3",
|
"version": "4.10.3",
|
||||||
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz",
|
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz",
|
||||||
@@ -18823,6 +18844,16 @@
|
|||||||
"name": "@yaak/auth-apikey",
|
"name": "@yaak/auth-apikey",
|
||||||
"version": "0.1.0"
|
"version": "0.1.0"
|
||||||
},
|
},
|
||||||
|
"plugins/auth-aws": {
|
||||||
|
"name": "@yaak/auth-aws",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"dependencies": {
|
||||||
|
"aws4": "^1.13.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/aws4": "^1.11.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"plugins/auth-basic": {
|
"plugins/auth-basic": {
|
||||||
"name": "@yaak/auth-basic",
|
"name": "@yaak/auth-basic",
|
||||||
"version": "0.1.0"
|
"version": "0.1.0"
|
||||||
|
|||||||
11
package.json
11
package.json
@@ -7,16 +7,17 @@
|
|||||||
"url": "git+https://github.com/mountain-loop/yaak.git"
|
"url": "git+https://github.com/mountain-loop/yaak.git"
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
"packages/common-lib",
|
||||||
"packages/plugin-runtime",
|
"packages/plugin-runtime",
|
||||||
"packages/plugin-runtime-types",
|
"packages/plugin-runtime-types",
|
||||||
"packages/common-lib",
|
"plugins/action-copy-curl",
|
||||||
|
"plugins/action-copy-grpcurl",
|
||||||
"plugins/auth-apikey",
|
"plugins/auth-apikey",
|
||||||
|
"plugins/auth-aws",
|
||||||
"plugins/auth-basic",
|
"plugins/auth-basic",
|
||||||
"plugins/auth-bearer",
|
"plugins/auth-bearer",
|
||||||
"plugins/auth-jwt",
|
"plugins/auth-jwt",
|
||||||
"plugins/auth-oauth2",
|
"plugins/auth-oauth2",
|
||||||
"plugins/action-copy-curl",
|
|
||||||
"plugins/action-copy-grpcurl",
|
|
||||||
"plugins/filter-jsonpath",
|
"plugins/filter-jsonpath",
|
||||||
"plugins/filter-xpath",
|
"plugins/filter-xpath",
|
||||||
"plugins/importer-curl",
|
"plugins/importer-curl",
|
||||||
@@ -25,7 +26,6 @@
|
|||||||
"plugins/importer-postman",
|
"plugins/importer-postman",
|
||||||
"plugins/importer-yaak",
|
"plugins/importer-yaak",
|
||||||
"plugins/template-function-cookie",
|
"plugins/template-function-cookie",
|
||||||
"plugins/template-function-timestamp",
|
|
||||||
"plugins/template-function-encode",
|
"plugins/template-function-encode",
|
||||||
"plugins/template-function-fs",
|
"plugins/template-function-fs",
|
||||||
"plugins/template-function-hash",
|
"plugins/template-function-hash",
|
||||||
@@ -34,13 +34,14 @@
|
|||||||
"plugins/template-function-regex",
|
"plugins/template-function-regex",
|
||||||
"plugins/template-function-request",
|
"plugins/template-function-request",
|
||||||
"plugins/template-function-response",
|
"plugins/template-function-response",
|
||||||
|
"plugins/template-function-timestamp",
|
||||||
"plugins/template-function-uuid",
|
"plugins/template-function-uuid",
|
||||||
"plugins/template-function-xml",
|
"plugins/template-function-xml",
|
||||||
"plugins/themes-yaak",
|
"plugins/themes-yaak",
|
||||||
"src-tauri",
|
"src-tauri",
|
||||||
"src-tauri/yaak-crypto",
|
"src-tauri/yaak-crypto",
|
||||||
"src-tauri/yaak-git",
|
|
||||||
"src-tauri/yaak-fonts",
|
"src-tauri/yaak-fonts",
|
||||||
|
"src-tauri/yaak-git",
|
||||||
"src-tauri/yaak-license",
|
"src-tauri/yaak-license",
|
||||||
"src-tauri/yaak-mac-window",
|
"src-tauri/yaak-mac-window",
|
||||||
"src-tauri/yaak-models",
|
"src-tauri/yaak-models",
|
||||||
|
|||||||
49
plugins/auth-aws/README.md
Normal file
49
plugins/auth-aws/README.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# AWS Signature Version 4 Auth
|
||||||
|
|
||||||
|
A plugin for authenticating AWS-compatible requests using the
|
||||||
|
[AWS Signature Version 4 signing process](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html).
|
||||||
|
This enables secure, signed requests to AWS services (or any S3-compatible APIs like
|
||||||
|
Cloudflare R2).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This plugin provides AWS Signature authentication for API requests in Yaak. SigV4 is used
|
||||||
|
by nearly all AWS APIs to verify the authenticity and integrity of requests using
|
||||||
|
cryptographic signatures.
|
||||||
|
|
||||||
|
With this plugin, you can securely sign requests to AWS services such as S3, STS, Lambda,
|
||||||
|
API Gateway, DynamoDB, and more. You can also authenticate against S3-compatible services
|
||||||
|
like **Cloudflare R2**, **MinIO**, or **Wasabi**.
|
||||||
|
|
||||||
|
## How AWS Signature Version 4 Works
|
||||||
|
|
||||||
|
SigV4 signs requests by creating a hash of key request components (method, URL, headers,
|
||||||
|
and optionally the payload) using your AWS credentials. The resulting HMAC signature is
|
||||||
|
added in the `Authorization` header along with credential scope metadata.
|
||||||
|
|
||||||
|
Example header:
|
||||||
|
|
||||||
|
```
|
||||||
|
Authorization: AWS4-HMAC-SHA256 Credential=AKIA…/20251011/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=abcdef123456…
|
||||||
|
```
|
||||||
|
|
||||||
|
Each request must include a timestamp (`X-Amz-Date`) and may include a session token if
|
||||||
|
using temporary credentials.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The plugin presents the following fields:
|
||||||
|
|
||||||
|
- **Access Key ID** – Your AWS access key identifier
|
||||||
|
- **Secret Access Key** – The secret associated with the access key
|
||||||
|
- **Session Token** *(optional)* – Used for temporary or assumed-role credentials (treated as secret)
|
||||||
|
- **Region** – AWS region (e.g., `us-east-1`)
|
||||||
|
- **Service** – AWS service identifier (e.g., `sts`, `s3`, `execute-api`)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
1. Configure a request, folder, or workspace to use **AWS SigV4 Authentication**
|
||||||
|
2. Enter your AWS credentials and target service/region
|
||||||
|
3. The plugin will automatically sign outgoing requests with valid SigV4 headers
|
||||||
23
plugins/auth-aws/package.json
Normal file
23
plugins/auth-aws/package.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "@yaak/auth-aws",
|
||||||
|
"displayName": "AWS SigV4",
|
||||||
|
"description": "Authenticate requests using AWS SigV4 signing",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/mountain-loop/yaak.git",
|
||||||
|
"directory": "plugins/auth-aws"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"version": "0.1.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "yaakcli build",
|
||||||
|
"dev": "yaakcli dev",
|
||||||
|
"lint": "tsc --noEmit && eslint . --ext .ts,.tsx"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"aws4": "^1.13.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/aws4": "^1.11.6"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
plugins/auth-aws/screenshot.png
Normal file
BIN
plugins/auth-aws/screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 790 KiB |
97
plugins/auth-aws/src/index.ts
Normal file
97
plugins/auth-aws/src/index.ts
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import type { CallHttpAuthenticationResponse } from '@yaakapp-internal/plugins';
|
||||||
|
import type { PluginDefinition } from '@yaakapp/api';
|
||||||
|
import aws4 from 'aws4';
|
||||||
|
import type { Request } from 'aws4';
|
||||||
|
import { URL } from 'node:url';
|
||||||
|
|
||||||
|
export const plugin: PluginDefinition = {
|
||||||
|
authentication: {
|
||||||
|
name: 'auth-aws-sig-v4',
|
||||||
|
label: 'AWS Signature',
|
||||||
|
shortLabel: 'AWS v4',
|
||||||
|
args: [
|
||||||
|
{ name: 'accessKeyId', label: 'Access Key ID', type: 'text', password: true },
|
||||||
|
{
|
||||||
|
name: 'secretAccessKey',
|
||||||
|
label: 'Secret Access Key',
|
||||||
|
type: 'text',
|
||||||
|
password: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'service',
|
||||||
|
label: 'Service Name',
|
||||||
|
type: 'text',
|
||||||
|
defaultValue: 'sts',
|
||||||
|
placeholder: 'sts',
|
||||||
|
description: 'The service that is receiving the request (sts, s3, sqs, ...)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'region',
|
||||||
|
label: 'Region',
|
||||||
|
type: 'text',
|
||||||
|
placeholder: 'us-east-1',
|
||||||
|
description: 'The region that is receiving the request (defaults to us-east-1)',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sessionToken',
|
||||||
|
label: 'Session Token',
|
||||||
|
type: 'text',
|
||||||
|
password: true,
|
||||||
|
optional: true,
|
||||||
|
description: 'Only required if you are using temporary credentials',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onApply(_ctx, { values, ...args }): CallHttpAuthenticationResponse {
|
||||||
|
const accessKeyId = String(values.accessKeyId || '');
|
||||||
|
const secretAccessKey = String(values.secretAccessKey || '');
|
||||||
|
const sessionToken = String(values.sessionToken || '') || undefined;
|
||||||
|
|
||||||
|
const url = new URL(args.url);
|
||||||
|
|
||||||
|
const headers: NonNullable<Request['headers']> = {};
|
||||||
|
for (const headerName of ['content-type', 'host', 'x-amz-date', 'x-amz-security-token']) {
|
||||||
|
const v = args.headers.find((h) => h.name.toLowerCase() === headerName);
|
||||||
|
if (v != null) {
|
||||||
|
headers[headerName] = v.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support body signing here
|
||||||
|
headers['x-amz-content-sha256'] = 'UNSIGNED-PAYLOAD';
|
||||||
|
|
||||||
|
const signature = aws4.sign(
|
||||||
|
{
|
||||||
|
host: url.host,
|
||||||
|
method: args.method,
|
||||||
|
path: url.pathname + (url.search || '') || undefined,
|
||||||
|
service: String(values.service || 'sts') || undefined,
|
||||||
|
region: String(values.region || 'us-east-1') || undefined,
|
||||||
|
headers,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessKeyId,
|
||||||
|
secretAccessKey,
|
||||||
|
sessionToken,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// After signing, aws4 will set:
|
||||||
|
// - opts.headers["Authorization"]
|
||||||
|
// - opts.headers["X-Amz-Date"]
|
||||||
|
// - optionally content sha256 header etc
|
||||||
|
|
||||||
|
console.log('ADDING STUFF', signature);
|
||||||
|
|
||||||
|
if (signature.headers == null) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
setHeaders: Object.entries(signature.headers)
|
||||||
|
.filter(([name]) => name !== 'content-type') // Don't add this because we already have it
|
||||||
|
.map(([name, value]) => ({ name, value: String(value || '') })),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
3
plugins/auth-aws/tsconfig.json
Normal file
3
plugins/auth-aws/tsconfig.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user