Skip to content

Commit fcadf92

Browse files
committed
simplify to just self-sign
1 parent 603145d commit fcadf92

File tree

6 files changed

+155
-20
lines changed

6 files changed

+155
-20
lines changed

rest/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ Where possible, we use [httpbingo.org](https://httpbingo.org) as our REST endpoi
1111
- [postbody](postbody) shows how a POST body can be automatically filled with field arguments with `Content-Type:application/x-www-form-urlencoded`. This is the easiest way to send postbodies down the REST API
1212
- [restWithConfigYaml](restWithConfigYaml) shows how REST query parameters can also be fetched from `config.yaml`--this allows you to keep your SDL code separate from your secrets.
1313
- [restWithParameters](restWithParameters) shows how GraphQL field arguments are automatically added to the REST call--there is nothing for you to do!
14+
- [tls](tls) shows how to use `@rest(tls:)` using the local stepzen service

rest/tls/README.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# TLS
2+
3+
4+
For more inforamtion on using TLS in your REST apis and other services [see our documentation](https://www.ibm.com/docs/en/api-connect-graphql/saas?topic=directives-directive-rest#tls-string__title__1).
5+
6+
[Environment](https://www.ibm.com/docs/en/api-connect-graphql/saas?topic=environment-tls-configuration-properties). Check that the revision is newer than : 2025-11-18.
7+
8+
## Using `@rest(tls:)`
9+
10+
This examples demonstrates a number of StepZen capabilities:
11+
- Use of `@rest(tls:)`
12+
- stepzen service
13+
- Simple ecmascript capability for reshaping data.
14+
15+
## mTLS and certificates
16+
17+
API Connect for GraphQL supports mTLS and custom certificates (self-signed, private,
18+
etc.) by using using a combination of a `@rest(tls:)` argument
19+
that refers to a configuration in the `config.yaml`
20+
21+
When the tls entry is given the name of a configuration entry, you can provide
22+
- `ca` - the server `ca` or `ca` chain (starting with the leaf certificate)
23+
- 'cert` - the client certificate
24+
- `key` - the client certifcate key
25+
The data should be in PEM format.
26+
27+
In our examples, we have two configuration: `selfsign` with a `ca` entry and `selfsignedmtls` with all three entries.
28+
29+
TLS 1.2 and 1.3 are supported. TLS 1.0 and 1.1 are not supported.
30+
31+
## Try it out!
32+
33+
`rest_self` in tls.graphql provides an example of self signed certificates by pointing to the `selfsign` resource in config.yaml. That configuration contains `ca: STEPZEN_SERVER_CRT`
34+
During `stepzen deploy`, the `STEPZEN_SERVER_CRT` environment variable is expanded and the result will be a yaml that looks like:
35+
```
36+
configurationset:
37+
- configuration:
38+
name: selfsign
39+
ca: |
40+
-----BEGIN CERTIFICATE-----
41+
MIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL
42+
...
43+
-----END CERTIFICATE-----
44+
```
45+
46+
The `selfsignedmtls` configuration contains an example mutual TLS configuration.
47+
48+
Two safe approaches are to set the environment variables from secrets or to have a `.env` file.
49+
50+
See tricks below for some possible hurdles.
51+
52+
53+
### Running a test
54+
55+
Testing mTLS or self-signed certificates locally is best done using local API Connect for GraphQL.
56+
In the following, we'll generate the certificates using openssl, use openssl to for trivialself-signed cert servers
57+
and use the stepzen cli local service mode as a client.
58+
59+
#### Steps
60+
```
61+
stepzen service start
62+
stepzen login --config ~/.stepzen/stepzen-config.local.yaml
63+
(cd tests; make env)
64+
stepzen deploy
65+
66+
# start trivial local TLS server using openssl
67+
# enable DEBUG if there are issues
68+
((cd tests; make run_validation_server_self_sign) &
69+
# wait until it gets establish 1-30s
70+
71+
# run the actual tests
72+
stepzen request -f operations.graphql
73+
74+
# cleanup
75+
stepzen service stop
76+
# restore your SaaS or other credentials
77+
```
78+
79+
80+
### Tricks
81+
82+
You can set `STEPZEN_*` env variables in .env or using export.
83+
84+
For example:
85+
```
86+
export STEPZEN_SERVER_CRT=`cat server.pem`
87+
```
88+
will set STEPZEN_SERVER_CRT to something like this:
89+
```
90+
-----BEGIN CERTIFICATE-----\nMIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL\nBQA....\nEUhqWbTk+y13A1OPfWbJu82zTKfJFvCAUgCf -----END CERTIFICATE-----"
91+
```
92+
93+
Be aware that the `\n` will show up as spaces if you do echo $STEPZEN_SERVER_CRT
94+
95+
To double check, you'll want to do something like this:
96+
```
97+
cat <<EOF
98+
$STEPZEN_SERVER_CRT
99+
EOF
100+
```
101+
or use techniques outlined in Misconfigured config.yaml below.
102+
103+
You can also set the env variables in `.env`. In that case, you can either replace the line breaks with `\n` or simply quote them:
104+
```
105+
STEPZEN_SERVER_CRT="-----BEGIN CERTIFICATE-----\nMIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL\n...\n-----END CERTIFICATE-----"
106+
```
107+
or
108+
```
109+
STEPZEN_SERVER_CRT="-----BEGIN CERTIFICATE-----
110+
MIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL
111+
...
112+
-----END CERTIFICATE-----"
113+
```
114+
115+
116+
### Misconfigured config.yaml
117+
118+
You can check if the config.yaml being uploaded by running
119+
```
120+
DEBUG="stepzen:sdk:trace" stepzen deploy
121+
```
122+
and looking for the configuration. Useful if the .env or exported variables are not
123+
as expected in the config.yaml or if you've directly placed the data in the `config.yaml`
124+
that it is as you expected.
125+
126+
You are looking for something that looks like:
127+
```
128+
"configuration":{"configurationset":[{"configuration":{"name":"selfsign","ca":
129+
"-----BEGIN CERTIFICATE-----\nMIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL\nBQAwbTE...
130+
```
131+
notice the '\n'. If you see spaces you've done something wrong upsteram.
132+
133+
134+
### Debugging
135+
You can debug using stepzen request by adding `-H "stepzen-debug-level: 1"`
136+
```
137+
stepzen request '{rest_self}' -H "stepzen-debug-level: 1"
138+
```
139+
and you can check the output for issues. You can check if tls values are being passed by looking for the tls
140+
block. In this case for mutual tls, we'll have:
141+
```
142+
"tls": {
143+
"clientCertificate": {
144+
"keyPresent": true,
145+
"present": true
146+
},
147+
"serverRootCA": {
148+
"present": true
149+
}
150+
},
151+
```

rest/tls/operations.graphql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
query run {
22
rest_self
3-
rest_self_mtls
43
}

rest/tls/stepzen.config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"endpoint": "api/miscellaneous"
2+
"endpoint": "api/tls"
33
}

rest/tls/tests/Makefile

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,8 @@ server.crt:
1515
-subj "/C=US/ST=California/L=San Jose/O=LOCALSERVER/OU=Com/CN=localhost" -nodes \
1616
-addext "subjectAltName = DNS:localhost, DNS:host.docker.internal"
1717

18-
run_validation_server_self_sign_mtls: server.crt client.crt
19-
openssl s_server -accept 9443 -cert server.crt -key server.key -Verify 2 -CAfile client.crt $(DEBUG) -www
20-
21-
run_validation_client_self_sign_mtls: client.crt
22-
curl --cert client.crt --key client.key --cacert server.crt https://localhost:9443 -debug
18+
run_validation_client_self_sign: client.crt
19+
curl --cacert server.crt https://localhost:9443 -debug
2320

2421
run_validation_server_self_sign: server.crt
2522
openssl s_server -accept 8443 -cert server.crt -key server.key $(DEBUG) -www

rest/tls/tls.graphql

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,4 @@ type Query {
1111
function transformREST(s) { return JSON.stringify({data100: s.length>100, accept_8443: s.includes("-accept 8443")})}
1212
"""
1313
)
14-
15-
"""
16-
will contact localhost using host.docker.internal and 9443 and mtls configuration
17-
the ecmascript is used to repackage any content coming back (openssl s_server returns html)
18-
"""
19-
rest_self_mtls: JSON
20-
@rest(
21-
endpoint: "https://host.docker.internal:9443/"
22-
tls: "selfsignedmtls"
23-
ecmascript: """
24-
function transformREST(s) { return JSON.stringify({data100: s.length>100, accept_9443: s.includes("-accept 9443")})}
25-
"""
26-
)
2714
}

0 commit comments

Comments
 (0)