Skip to content
This repository was archived by the owner on Aug 12, 2025. It is now read-only.

Commit 9d61aa9

Browse files
thisisaaronlandsfomuseumbotthisisaaronland
authored
Add cmd/aws-sign-request tool (#5)
* snapshot: block out cmd/aws-sign-request, untested * Make aws-sign-request work, docs --------- Co-authored-by: sfomuseumbot <sfomuseumbot@localhost> Co-authored-by: thisisaaronland <thisisaaronland@localhost>
1 parent 3e55b50 commit 9d61aa9

File tree

3 files changed

+209
-3
lines changed

3 files changed

+209
-3
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ cli:
66
go build -mod $(GOMOD) -ldflags="$(LDFLAGS)" -o bin/aws-get-credentials cmd/aws-get-credentials/main.go
77
go build -mod $(GOMOD) -ldflags="$(LDFLAGS)" -o bin/aws-cognito-credentials cmd/aws-cognito-credentials/main.go
88
go build -mod $(GOMOD) -ldflags="$(LDFLAGS)" -o bin/aws-set-env cmd/aws-set-env/main.go
9+
go build -mod $(GOMOD) -ldflags="$(LDFLAGS)" -o bin/aws-sign-request cmd/aws-sign-request/main.go
910
go build -mod $(GOMOD) -ldflags="$(LDFLAGS)" -o bin/aws-credentials-json-to-ini cmd/aws-credentials-json-to-ini/main.go

README.md

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ This package targets [aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2/). For
1212

1313
```
1414
$> make cli
15-
go build -mod vendor -o bin/aws-mfa-session cmd/aws-mfa-session/main.go
16-
go build -mod vendor -o bin/aws-get-credentials cmd/aws-get-credentials/main.go
17-
go build -mod vendor -o bin/aws-set-env cmd/aws-set-env/main.go
15+
go build -mod vendor -ldflags="-s -w" -o bin/aws-mfa-session cmd/aws-mfa-session/main.go
16+
go build -mod vendor -ldflags="-s -w" -o bin/aws-get-credentials cmd/aws-get-credentials/main.go
17+
go build -mod vendor -ldflags="-s -w" -o bin/aws-cognito-credentials cmd/aws-cognito-credentials/main.go
18+
go build -mod vendor -ldflags="-s -w" -o bin/aws-set-env cmd/aws-set-env/main.go
19+
go build -mod vendor -ldflags="-s -w" -o bin/aws-sign-request cmd/aws-sign-request/main.go
20+
go build -mod vendor -ldflags="-s -w" -o bin/aws-credentials-json-to-ini cmd/aws-credentials-json-to-ini/main.go
1821
```
1922

2023
## aws-cognito-credentials
@@ -141,6 +144,74 @@ Usage of ./bin/aws-set-env:
141144
Require AWS_SESSION_TOKEN environment variable (default true)
142145
```
143146

147+
### aws-sign-request
148+
149+
`aws-sign-request` signs a HTTP request with an AWS "v4" signature, optionally executing the request and emitting the output to STDOUT or writing the request itself to STDOUT.
150+
151+
```
152+
$> ./bin/aws-sign-request -h
153+
Usage of ./bin/aws-sign-request:
154+
-api-signing-name string
155+
The name the API uses to identify the service the request is scoped to.
156+
-api-signing-region string
157+
If empty then the value of the region associated with the AWS config/credentials will be used.
158+
-credentials-uri string
159+
A valid aaronland/go-aws-auth config URI.
160+
-do
161+
If true then execute the signed request and output the response to STDOUT.
162+
-header value
163+
Zero or more HTTP headers to assign to the request in the form of key=value.
164+
-method string
165+
A valid HTTP method. (default "GET")
166+
-uri string
167+
The URI you are trying to sign.
168+
```
169+
170+
For example, to call a Lambda Function URL:
171+
172+
```
173+
$> bin/aws-sign-request \
174+
-credentials-uri 'aws://{REGION}?credentials=iam:' \
175+
-api-signing-name 'lambda' \
176+
-uri https://{GIBBERISH}.lambda-url.{REGION}.on.aws/api/point-in-polygon \
177+
-method POST \
178+
-do \
179+
'{"latitude": 25.0, "longitude": -45.6 }' \
180+
181+
| jq
182+
183+
{
184+
"places": [
185+
{
186+
"wof:id": "404528709",
187+
"wof:parent_id": "-1",
188+
"wof:name": "North Atlantic Ocean",
189+
"wof:country": "",
190+
"wof:placetype": "ocean",
191+
"mz:latitude": 0,
192+
"mz:longitude": 0,
193+
"mz:min_latitude": 24.965357,
194+
"mz:min_longitude": 0,
195+
"mz:max_latitude": -45.616087,
196+
"mz:max_longitude": -45.570425,
197+
"mz:is_current": 1,
198+
"mz:is_deprecated": -1,
199+
"mz:is_ceased": -1,
200+
"mz:is_superseded": 0,
201+
"mz:is_superseding": 0,
202+
"edtf:inception": "",
203+
"edtf:cessation": "",
204+
"wof:supersedes": [],
205+
"wof:superseded_by": [],
206+
"wof:belongsto": [],
207+
"wof:path": "404/528/709/404528709.geojson",
208+
"wof:repo": "whosonfirst-data-admin-xy",
209+
"wof:lastmodified": 1690923898
210+
}
211+
]
212+
}
213+
```
214+
144215
## See also:
145216

146217
* https://github.com/aws/aws-sdk-go-v2/

cmd/aws-sign-request/main.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// aws-sign-request signs a HTTP request with an AWS "v4" signature, optionally executing the
2+
// request and emitting the output to STDOUT or writing the request itself to STDOUT.
3+
package main
4+
5+
import (
6+
"context"
7+
"crypto/sha256"
8+
"flag"
9+
"fmt"
10+
"io"
11+
"log"
12+
"net/http"
13+
"os"
14+
"strings"
15+
"time"
16+
17+
"github.com/aaronland/go-aws-auth"
18+
"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
19+
"github.com/sfomuseum/go-flags/multi"
20+
)
21+
22+
func main() {
23+
24+
var headers multi.KeyValueString
25+
26+
var api_signing_name string
27+
var api_signing_region string
28+
29+
var credentials_uri string
30+
var method string
31+
var uri string
32+
var do bool
33+
34+
flag.StringVar(&api_signing_name, "api-signing-name", "", "The name the API uses to identify the service the request is scoped to.")
35+
flag.StringVar(&api_signing_region, "api-signing-region", "", "If empty then the value of the region associated with the AWS config/credentials will be used.")
36+
37+
flag.StringVar(&method, "method", "GET", "A valid HTTP method.")
38+
flag.StringVar(&uri, "uri", "", "The URI you are trying to sign.")
39+
flag.StringVar(&credentials_uri, "credentials-uri", "", "A valid aaronland/go-aws-auth config URI.")
40+
flag.BoolVar(&do, "do", false, "If true then execute the signed request and output the response to STDOUT.")
41+
flag.Var(&headers, "header", "Zero or more HTTP headers to assign to the request in the form of key=value.")
42+
43+
flag.Parse()
44+
45+
ctx := context.Background()
46+
47+
body_r := strings.NewReader(strings.Join(flag.Args(), " "))
48+
49+
//
50+
51+
cfg, err := auth.NewConfig(ctx, credentials_uri)
52+
53+
if err != nil {
54+
log.Fatalf("Failed to create new config, %v", err)
55+
}
56+
57+
creds, err := cfg.Credentials.Retrieve(ctx)
58+
59+
if err != nil {
60+
log.Fatalf("Failed to derive credentials from config, %v", err)
61+
}
62+
63+
if api_signing_region == "" {
64+
api_signing_region = cfg.Region
65+
}
66+
67+
// https://github.com/aws/aws-sdk-go-v2/blob/main/aws/signer/v4/v4.go#L287
68+
69+
body_sha256 := ""
70+
71+
if body_r.Len() > 0 {
72+
73+
h := sha256.New()
74+
75+
_, err := io.Copy(h, body_r)
76+
77+
if err != nil {
78+
log.Fatalf("Failed to hash request body, %v", err)
79+
}
80+
81+
body_sha256 = fmt.Sprintf("%x", h.Sum(nil))
82+
83+
_, err = body_r.Seek(0, 0)
84+
85+
if err != nil {
86+
log.Fatalf("Failed to rewind message body, %v", err)
87+
}
88+
}
89+
90+
req, err := http.NewRequest(method, uri, body_r)
91+
92+
if err != nil {
93+
log.Fatalf("Failed to create new HTTP request, %v", err)
94+
}
95+
96+
for _, h := range headers {
97+
req.Header.Set(h.Key(), h.Value().(string))
98+
}
99+
100+
signer := v4.NewSigner()
101+
102+
err = signer.SignHTTP(ctx, creds, req, body_sha256, api_signing_name, api_signing_region, time.Now())
103+
104+
if err != nil {
105+
log.Fatalf("Failed to sign request, %v", err)
106+
}
107+
108+
if !do {
109+
110+
err = req.Write(os.Stdout)
111+
112+
if err != nil {
113+
log.Fatalf("Failed to write request, %v", err)
114+
}
115+
116+
return
117+
}
118+
119+
cl := http.Client{}
120+
rsp, err := cl.Do(req)
121+
122+
if err != nil {
123+
log.Fatalf("Failed to execute request, %v", err)
124+
}
125+
126+
defer rsp.Body.Close()
127+
128+
_, err = io.Copy(os.Stdout, rsp.Body)
129+
130+
if err != nil {
131+
log.Fatalf("Failed to read response, %v", err)
132+
}
133+
134+
}

0 commit comments

Comments
 (0)