샘플
aws4 1.13.2: sign an HTTP request with AWS Signature Version 4 credentials using aws4.sign
검증된 샘플 — npm aws4 1.13.2: sign an HTTP request with AWS Signature Version 4 credentials using aws4.sign. node 22 · linux alpine/x64 · docker에서 contract를 실행해…
sha256:8f8ba492115e5ad229fe51119e4d4882ddb4405af0d88c7720ad4cfc4d2526ab
이 네트워크가 제공하는 것은 하나입니다. 빌드되는 샘플. 샌드박스에서 돌리고 서명된 영수증을 보관합니다. 등급을 매기지 않고 무엇도 보증하지 않습니다 — 같은 코드가 당신 환경에서 빌드되는지는 측정한 적이 없습니다.
통과한 계약 영수증을 낸 서로 다른 서명 키의 수입니다. 하나면 작성자 혼자이고, 둘 이상이면 다른 사람도 빌드했다는 뜻입니다. 키는 스스로 만드는 것이고 뒤에 등록된 신원이 없으므로, 세는 것은 사람이 아니라 키입니다.
MIT-0
실행 증거
선언된 환경과 서명된 실행을 분리해 두었습니다. 이 샘플이 무엇을 어디서 실행했는지 그대로 볼 수 있습니다.
- 증거 기준
- 서명된 컨트랙트 통과
- 검증 영수증
- 1
- 빌드한 서명 키
- 1
선언된 환경
linux 24 · ubuntu · glibc 2.39 x64 npm
검증 실행 환경
| 환경 | 컨트랙트 | 단계 | 실행일 |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5… |
2026-08-27 |
케이스
HOW- 목표
- sign an HTTP request with AWS Signature Version 4 credentials using aws4.sign
- 패키지
- 심벌
-
- aws4.sign
- 생성일
- 2026-08-27T20:26:37Z
컨트랙트
- assert aws4.sign populates Authorization, X-Amz-Date, and Host headers on HTTP request options
- assert Authorization header follows AWS4-HMAC-SHA256 format containing Credential, SignedHeaders, and Signature
- assert aws4.sign sets Content-Type and Content-Length headers for POST requests with body content
- assert aws4.sign adds X-Amz-Security-Token header and includes it in signed headers when sessionToken is provided
- assert aws4.sign computes SHA256 payload hash and sets X-Amz-Content-Sha256 header for S3 service requests
- assert aws4.sign with signQuery option embeds SigV4 parameters into query string without Authorization header
- assert aws4.RequestSigner resolves service name and AWS region automatically from amazonaws.com hostnames
- assert aws4.RequestSigner exposes canonicalString, stringToSign, and signature generation methods
파일
- PROMPT.md
- csx.json
- package-lock.json
- package.json
- spec.json
- src/index.js
- test/contract.mjs
소스
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: sign an HTTP request with AWS Signature Version 4 credentials using aws4.sign
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:npm/aws4@1.13.2
Demonstrate these symbols/APIs:
- aws4.sign
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
{"case":{"caseId":"case:sha256:2ae9008937e9bf62e34a804a0c03d8e3db4181d04855e3b1952c2f4370e6d4af","contract":["assert aws4.sign populates Authorization, X-Amz-Date, and Host headers on HTTP request options","assert Authorization header follows AWS4-HMAC-SHA256 format containing Credential, SignedHeaders, and Signature","assert aws4.sign sets Content-Type and Content-Length headers for POST requests with body content","assert aws4.sign adds X-Amz-Security-Token header and includes it in signed headers when sessionToken is provided","assert aws4.sign computes SHA256 payload hash and sets X-Amz-Content-Sha256 header for S3 service requests","assert aws4.sign with signQuery option embeds SigV4 parameters into query string without Authorization header","assert aws4.RequestSigner resolves service name and AWS region automatically from amazonaws.com hostnames","assert aws4.RequestSigner exposes canonicalString, stringToSign, and signature generation methods"],"goal":"sign an HTTP request with AWS Signature Version 4 credentials using aws4.sign","kind":"HOW","packages":["pkg:npm/aws4@1.13.2"],"schemaVersion":1,"symbols":["aws4.sign"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"npm","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/aws4@1.13.2"],"schemaVersion":1,"subject":"pkg:npm/aws4@1.13.2","symbols":["aws4.sign"],"verifierAdapter":"node-typescript@1"}
{
"name": "sample-aws4",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sample-aws4",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"aws4": "1.13.2"
}
},
"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"
}
}
}
{
"name": "sample-aws4",
"version": "1.0.0",
"private": true,
"description": "Clean-room verification of pkg:npm/aws4@1.13.2",
"main": "src/index.js",
"license": "MIT-0",
"dependencies": {
"aws4": "1.13.2"
}
}
{
"schemaVersion": 1,
"goal": "sign an HTTP request with AWS Signature Version 4 credentials using aws4.sign",
"kind": "HOW",
"packages": [
"pkg:npm/aws4@1.13.2"
],
"symbols": [
"aws4.sign"
]
}
'use strict';
const aws4 = require('aws4');
/**
* Signs an HTTP request options object with AWS Signature Version 4 credentials.
* Modifies and returns the request options with Authorization and X-Amz-Date headers.
*
* @param {object} request - Request options (host/hostname, path, method, headers, body, service, region).
* @param {object} [credentials] - AWS credentials { accessKeyId, secretAccessKey, sessionToken }.
* @returns {object} Signed request object.
*/
function signRequest(request, credentials) {
return aws4.sign(request, credentials);
}
/**
* Signs an HTTP request using query parameters instead of Authorization header.
* Useful for generating pre-signed URLs.
*
* @param {object} request - Request options.
* @param {object} [credentials] - AWS credentials.
* @returns {object} Signed request object with query parameters populated on path.
*/
function signQuery(request, credentials) {
const req = Object.assign({}, request, { signQuery: true });
return aws4.sign(req, credentials);
}
/**
* Signs an HTTP request using temporary STS credentials (including session token).
* Populates X-Amz-Security-Token header.
*
* @param {object} request - Request options.
* @param {object} credentials - AWS credentials containing sessionToken.
* @returns {object} Signed request object.
*/
function signWithSessionToken(request, credentials) {
return aws4.sign(request, credentials);
}
/**
* Signs an S3 request with automatic SHA256 payload calculation.
*
* @param {object} request - Request options for S3 service.
* @param {object} [credentials] - AWS credentials.
* @returns {object} Signed request object with X-Amz-Content-Sha256 header.
*/
function signS3Request(request, credentials) {
const req = Object.assign({ service: 's3' }, request);
return aws4.sign(req, credentials);
}
/**
* Creates a RequestSigner instance for custom inspection and step-by-step signing.
*
* @param {object|string} request - Request options or URL string.
* @param {object} [credentials] - AWS credentials.
* @returns {aws4.RequestSigner} RequestSigner instance.
*/
function createRequestSigner(request, credentials) {
return new aws4.RequestSigner(request, credentials);
}
module.exports = {
signRequest,
signQuery,
signWithSessionToken,
signS3Request,
createRequestSigner,
aws4,
};
import assert from 'node:assert';
import crypto from 'node:crypto';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const aws4 = require('aws4');
const {
signRequest,
signQuery,
signWithSessionToken,
signS3Request,
createRequestSigner,
} = require('../src/index.js');
const dummyCredentials = {
accessKeyId: 'mock-access-key-id',
secretAccessKey: 'mock-secret-access-key',
};
async function runContract() {
// 1. assert aws4.sign populates Authorization, X-Amz-Date, and Host headers on HTTP request options
const req1 = {
host: 'sqs.us-east-1.amazonaws.com',
path: '/?Action=ListQueues&Version=2012-11-05',
service: 'sqs',
region: 'us-east-1',
headers: {
'Date': 'Mon, 09 Sep 2024 00:00:00 GMT',
},
};
const signed1 = signRequest(req1, dummyCredentials);
assert.ok(signed1.headers.Authorization, 'Authorization header should be set');
assert.strictEqual(signed1.headers['X-Amz-Date'], '20240909T000000Z', 'X-Amz-Date should match ISO-like format');
assert.strictEqual(signed1.headers.Host, 'sqs.us-east-1.amazonaws.com', 'Host header should be set');
// 2. assert Authorization header follows AWS4-HMAC-SHA256 format containing Credential, SignedHeaders, and Signature
const authHeader = signed1.headers.Authorization;
assert.ok(
authHeader.startsWith('AWS4-HMAC-SHA256 Credential=mock-access-key-id/20240909/us-east-1/sqs/aws4_request'),
'Authorization must start with AWS4-HMAC-SHA256 and expected Credential scope'
);
assert.ok(authHeader.includes('SignedHeaders='), 'Authorization must contain SignedHeaders');
assert.ok(authHeader.includes('Signature='), 'Authorization must contain Signature');
const sigMatch = authHeader.match(/Signature=([a-f0-9]{64})/);
assert.ok(sigMatch && sigMatch[1].length === 64, 'Signature must be a 64-character hexadecimal string');
// 3. assert aws4.sign sets Content-Type and Content-Length headers for POST requests with body content
const postReq = {
host: 'dynamodb.us-east-1.amazonaws.com',
path: '/',
method: 'POST',
body: '{"TableName":"TestTable"}',
};
const signedPost = signRequest(postReq, dummyCredentials);
assert.strictEqual(
signedPost.headers['Content-Type'],
'application/x-www-form-urlencoded; charset=utf-8',
'Default Content-Type should be set for POST requests with body'
);
assert.strictEqual(
signedPost.headers['Content-Length'],
25,
'Content-Length must match byte length of payload'
);
// 4. assert aws4.sign adds X-Amz-Security-Token header and includes it in signed headers when sessionToken is provided
const stsCredentials = {
...dummyCredentials,
sessionToken: 'mock-session-token',
};
const stsReq = {
host: 'sqs.us-east-1.amazonaws.com',
path: '/',
};
const signedSts = signWithSessionToken(stsReq, stsCredentials);
assert.strictEqual(
signedSts.headers['X-Amz-Security-Token'],
'mock-session-token',
'X-Amz-Security-Token header should match session token'
);
assert.ok(
signedSts.headers.Authorization.toLowerCase().includes('x-amz-security-token'),
'Authorization SignedHeaders must include x-amz-security-token'
);
// 5. assert aws4.sign computes SHA256 payload hash and sets X-Amz-Content-Sha256 header for S3 service requests
const s3Payload = 'Sample payload for S3 upload';
const expectedS3Hash = crypto.createHash('sha256').update(s3Payload).digest('hex');
const s3Req = {
host: 'example-bucket.s3.amazonaws.com',
path: '/data.txt',
method: 'PUT',
body: s3Payload,
};
const signedS3 = signS3Request(s3Req, dummyCredentials);
assert.strictEqual(
signedS3.headers['X-Amz-Content-Sha256'],
expectedS3Hash,
'X-Amz-Content-Sha256 header must match SHA256 of the body'
);
// 6. assert aws4.sign with signQuery option embeds SigV4 parameters into query string without Authorization header
const queryReq = {
host: 'example-bucket.s3.amazonaws.com',
path: '/data.txt',
service: 's3',
region: 'us-east-1',
};
const signedQuery = signQuery(queryReq, dummyCredentials);
assert.strictEqual(signedQuery.headers.Authorization, undefined, 'Authorization header must not be set when signQuery is true');
assert.ok(signedQuery.path.includes('X-Amz-Algorithm=AWS4-HMAC-SHA256'), 'Path must contain X-Amz-Algorithm query param');
assert.ok(signedQuery.path.includes('X-Amz-Credential='), 'Path must contain X-Amz-Credential query param');
assert.ok(signedQuery.path.includes('X-Amz-Date='), 'Path must contain X-Amz-Date query param');
assert.ok(signedQuery.path.includes('X-Amz-SignedHeaders='), 'Path must contain X-Amz-SignedHeaders query param');
assert.ok(signedQuery.path.includes('X-Amz-Signature='), 'Path must contain X-Amz-Signature query param');
// 7. assert aws4.RequestSigner resolves service name and AWS region automatically from amazonaws.com hostnames
const signer = createRequestSigner({
host: 'dynamodb.eu-central-1.amazonaws.com',
path: '/',
}, dummyCredentials);
assert.strictEqual(signer.service, 'dynamodb', 'Service should be inferred as dynamodb from host');
assert.strictEqual(signer.region, 'eu-central-1', 'Region should be inferred as eu-central-1 from host');
// 8. assert aws4.RequestSigner exposes canonicalString, stringToSign, and signature generation methods
assert.strictEqual(typeof signer.canonicalString, 'function', 'canonicalString method should exist');
assert.strictEqual(typeof signer.stringToSign, 'function', 'stringToSign method should exist');
assert.strictEqual(typeof signer.signature, 'function', 'signature method should exist');
assert.strictEqual(typeof signer.authHeader, 'function', 'authHeader method should exist');
const canonical = signer.canonicalString();
assert.ok(canonical.startsWith('GET\n/'), 'Canonical request string should start with method and path');
const stringToSign = signer.stringToSign();
assert.ok(stringToSign.startsWith('AWS4-HMAC-SHA256\n'), 'String to sign must start with AWS4-HMAC-SHA256');
const signatureHex = signer.signature();
assert.strictEqual(typeof signatureHex, 'string');
assert.strictEqual(signatureHex.length, 64, 'Signature must be 64 characters hex');
console.log('Contract tests passed successfully.');
}
runContract().catch((err) => {
console.error('Contract test failed:', err);
process.exit(1);
});
오리진 시더
익명