Skip to content

Commit af4f0ac

Browse files
yaronfcursoragent
andcommitted
test: add WIMSE HTTP-sig conformance harness
Run the kanywst/wimsey sign-basic vectors against RFC 9421 sign/verify, with a thin profile overlay for WIMSE policy (forbidden alg/keyid, required params, tag, audience, max_age, content-digest). Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent de382d3 commit af4f0ac

2 files changed

Lines changed: 430 additions & 0 deletions

File tree

testdata/wimse/sign-basic.json

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
{
2+
"format": "wimse-conformance/v1",
3+
"suite": "httpsig",
4+
"id": "sign-basic",
5+
"spec": "draft-ietf-wimse-http-signature-06",
6+
"description": "WIMSE HTTP Message Signature (RFC 9421, ed25519) carrying a WIT, plus the inputs a verifier must reject",
7+
"pop_signing_key_seed_b64u": "CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQk",
8+
"issuer_verifying_key_b64u": "iojj3XQJ8ZX9UtstPLpdcspnCb8dlBIb83SIAbQPb1w",
9+
"verify_now": 1700000100,
10+
"label": "wimse",
11+
"components": [
12+
"\"@method\"",
13+
"\"@request-target\"",
14+
"\"content-type\"",
15+
"\"content-digest\"",
16+
"\"workload-identity-token\""
17+
],
18+
"params": {
19+
"created": 1700000000,
20+
"expires": 1700000300,
21+
"nonce": "abcd1111",
22+
"tag": "wimse-workload-to-workload",
23+
"wimse_aud": "https://service.example/transfer"
24+
},
25+
"request": {
26+
"method": "POST",
27+
"authority": "service.example",
28+
"path": "/transfer",
29+
"query": null,
30+
"headers": [
31+
[
32+
"Content-Type",
33+
"application/json"
34+
],
35+
[
36+
"Content-Digest",
37+
"sha-256=:TUu+Wcaq0iRCzeGZpqil8DRAX814+1qBwk7ySd4cRfE=:"
38+
],
39+
[
40+
"Workload-Identity-Token",
41+
"eyJ0eXAiOiJ3aXQrand0IiwiYWxnIjoiRWREU0EiLCJraWQiOiJpc3N1ZXIta2V5LTEifQ.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwic3ViIjoic3BpZmZlOi8vZXhhbXBsZS5vcmcvd29ya2xvYWQvYXBpIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDAsImp0aSI6ImExYjJjMyIsImNuZiI6eyJqd2siOnsiYWxnIjoiRWREU0EiLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Il9SY2tPRnFneDF0ay0zak5ZQy1oMlpIOTZfZHJFOFdPMXdMcXlEWHA5aGcifX19.gEOIwRVXNwJTSXRGBDPV4CQLRUFeKYx-oK_nwSxaxegepaEEcKbn1TIPacMI0rWR2M8kRikyzB4jkcudkUtXCA"
42+
]
43+
]
44+
},
45+
"body": "{\"amount\":100}",
46+
"wit": "eyJ0eXAiOiJ3aXQrand0IiwiYWxnIjoiRWREU0EiLCJraWQiOiJpc3N1ZXIta2V5LTEifQ.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwic3ViIjoic3BpZmZlOi8vZXhhbXBsZS5vcmcvd29ya2xvYWQvYXBpIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDAsImp0aSI6ImExYjJjMyIsImNuZiI6eyJqd2siOnsiYWxnIjoiRWREU0EiLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Il9SY2tPRnFneDF0ay0zak5ZQy1oMlpIOTZfZHJFOFdPMXdMcXlEWHA5aGcifX19.gEOIwRVXNwJTSXRGBDPV4CQLRUFeKYx-oK_nwSxaxegepaEEcKbn1TIPacMI0rWR2M8kRikyzB4jkcudkUtXCA",
47+
"signature_input": "wimse=(\"@method\" \"@request-target\" \"content-type\" \"content-digest\" \"workload-identity-token\");created=1700000000;expires=1700000300;nonce=\"abcd1111\";tag=\"wimse-workload-to-workload\";wimse-aud=\"https://service.example/transfer\"",
48+
"signature": "wimse=:7wug7wUAtTZkqCo8X2mMySacneAidDDsIldEAL7NLVYv+4c/wnQqClXBxEiuGZQgF6Q4qTnjHw46oEvq3/XYDw==:",
49+
"negative": [
50+
{
51+
"id": "forbidden-alg-parameter",
52+
"description": "the signature carries the `alg` parameter, which the profile forbids",
53+
"expect": "forbidden_parameter",
54+
"signature_input": "wimse=(\"@method\" \"@request-target\" \"content-type\" \"content-digest\" \"workload-identity-token\");created=1700000000;expires=1700000300;alg=\"ed25519\";nonce=\"abcd1111\";tag=\"wimse-workload-to-workload\";wimse-aud=\"https://service.example/transfer\"",
55+
"signature": "wimse=:7/gmpqDCKZYNgSsQtcVZp2nclqlx9OQk9u9/TQv7brNfF/HCR3iUGSByw+gG76DElEPrBPEMnFT/By8AzUwABg==:"
56+
},
57+
{
58+
"id": "forbidden-keyid-parameter",
59+
"description": "the signature carries the `keyid` parameter, which the profile forbids",
60+
"expect": "forbidden_parameter",
61+
"signature_input": "wimse=(\"@method\" \"@request-target\" \"content-type\" \"content-digest\" \"workload-identity-token\");created=1700000000;expires=1700000300;keyid=\"issuer-key-1\";nonce=\"abcd1111\";tag=\"wimse-workload-to-workload\";wimse-aud=\"https://service.example/transfer\"",
62+
"signature": "wimse=:Ue9Zw5RggvORbc4mcDtk6aBG20ddmCcp2fR7DbqF73AQHaMezs2nuMQCyj0ilIY0kiDrXoa/VO3xq2V7DKtTDQ==:"
63+
},
64+
{
65+
"id": "missing-nonce",
66+
"description": "the signature omits the mandatory `nonce` parameter",
67+
"expect": "missing_parameter",
68+
"signature_input": "wimse=(\"@method\" \"@request-target\" \"content-type\" \"content-digest\" \"workload-identity-token\");created=1700000000;expires=1700000300;tag=\"wimse-workload-to-workload\";wimse-aud=\"https://service.example/transfer\"",
69+
"signature": "wimse=:iq2jrPDHBRAtdh17iq3fYxOOHUwlp5Gz6eJSNRH2vkbt2WZJZRvxjTgeSkRXPZg3Ily1XoFVIKp9CB61HlzfCg==:"
70+
},
71+
{
72+
"id": "missing-expires",
73+
"description": "the signature omits the mandatory `expires` parameter",
74+
"expect": "missing_parameter",
75+
"signature_input": "wimse=(\"@method\" \"@request-target\" \"content-type\" \"content-digest\" \"workload-identity-token\");created=1700000000;nonce=\"abcd1111\";tag=\"wimse-workload-to-workload\";wimse-aud=\"https://service.example/transfer\"",
76+
"signature": "wimse=:aZQ+nRBonH4ANWM+yXqxPkwqsINAZ51jGN7sdgYW/z2pJK3C840b3Mu1HfKFURepNHYLeywVnzMpaEiPWIuVDw==:"
77+
},
78+
{
79+
"id": "missing-wimse-aud",
80+
"description": "the request signature omits the mandatory `wimse-aud` parameter",
81+
"expect": "missing_parameter",
82+
"signature_input": "wimse=(\"@method\" \"@request-target\" \"content-type\" \"content-digest\" \"workload-identity-token\");created=1700000000;expires=1700000300;nonce=\"abcd1111\";tag=\"wimse-workload-to-workload\"",
83+
"signature": "wimse=:yiAx6JLxQmJ8xp2jaS+3/mHCBORLgD4baGsX8GFFSfGW3m1gS241/2p7UvlgKLvLlylp/eQmJcsjPOjXc00QDQ==:"
84+
},
85+
{
86+
"id": "wrong-tag",
87+
"description": "the signature's `tag` is not `wimse-workload-to-workload`",
88+
"expect": "wrong_tag",
89+
"signature_input": "wimse=(\"@method\" \"@request-target\" \"content-type\" \"content-digest\" \"workload-identity-token\");created=1700000000;expires=1700000300;nonce=\"abcd1111\";tag=\"some-other-protocol\";wimse-aud=\"https://service.example/transfer\"",
90+
"signature": "wimse=:1TlIWI/ISc34P9z75NxLcaBNc3jSoCjPeSGSkYPBXsLfZXlyG6cllNxhUftjADUZQZlVYrlUPF9ntOs7QF4hCg==:"
91+
},
92+
{
93+
"id": "audience-mismatch",
94+
"description": "the signature was minted for a different service than the one verifying it",
95+
"expect": "audience_mismatch",
96+
"accept_audience": "https://other.example/inbox"
97+
},
98+
{
99+
"id": "tampered-body",
100+
"description": "the body no longer hashes to the signed `Content-Digest`",
101+
"expect": "content_digest_mismatch",
102+
"body": "{\"amount\":999}"
103+
},
104+
{
105+
"id": "rerouted-path",
106+
"description": "an intermediary changed `@path` after the signature was made",
107+
"expect": "invalid_signature",
108+
"request": {
109+
"method": "POST",
110+
"authority": "service.example",
111+
"path": "/admin",
112+
"query": null,
113+
"headers": [
114+
[
115+
"Content-Type",
116+
"application/json"
117+
],
118+
[
119+
"Content-Digest",
120+
"sha-256=:TUu+Wcaq0iRCzeGZpqil8DRAX814+1qBwk7ySd4cRfE=:"
121+
],
122+
[
123+
"Workload-Identity-Token",
124+
"eyJ0eXAiOiJ3aXQrand0IiwiYWxnIjoiRWREU0EiLCJraWQiOiJpc3N1ZXIta2V5LTEifQ.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwic3ViIjoic3BpZmZlOi8vZXhhbXBsZS5vcmcvd29ya2xvYWQvYXBpIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDAsImp0aSI6ImExYjJjMyIsImNuZiI6eyJqd2siOnsiYWxnIjoiRWREU0EiLCJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Il9SY2tPRnFneDF0ay0zak5ZQy1oMlpIOTZfZHJFOFdPMXdMcXlEWHA5aGcifX19.gEOIwRVXNwJTSXRGBDPV4CQLRUFeKYx-oK_nwSxaxegepaEEcKbn1TIPacMI0rWR2M8kRikyzB4jkcudkUtXCA"
125+
]
126+
]
127+
}
128+
},
129+
{
130+
"id": "created-in-future",
131+
"description": "the signature's `created` is ahead of the verifier's clock",
132+
"expect": "created_in_future",
133+
"verify_now": 1699999999
134+
},
135+
{
136+
"id": "too-old",
137+
"description": "the signature is still unexpired but older than the verifier's `max_age`",
138+
"expect": "too_old",
139+
"verify_now": 1700000120,
140+
"max_age": 30
141+
},
142+
{
143+
"id": "label-mismatch",
144+
"description": "the verifier only accepts a label the request does not carry",
145+
"expect": "label_mismatch",
146+
"accept_label": "other"
147+
},
148+
{
149+
"id": "missing-required-component",
150+
"description": "the verifier requires a component the signature does not cover",
151+
"expect": "missing_required_component",
152+
"required_components": [
153+
"\"authorization\""
154+
]
155+
}
156+
]
157+
}

0 commit comments

Comments
 (0)