|
| 1 | +# TLS |
| 2 | + |
| 3 | + |
| 4 | +For more information 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 | +## Using `@rest(tls:)` |
| 7 | + |
| 8 | +This examples demonstrates a number of API Connect for GraphQL capabilities: |
| 9 | +- Use of `@rest(tls:)` |
| 10 | +- stepzen service |
| 11 | +- Simple ecmascript capability for reshaping data. |
| 12 | + |
| 13 | +## mTLS and certificates |
| 14 | + |
| 15 | +API Connect for GraphQL supports mTLS and custom certificates (self-signed, private, |
| 16 | +etc.) by using using a combination of a `@rest(tls:)` argument |
| 17 | +that refers to a configuration in the `config.yaml` |
| 18 | + |
| 19 | +When the tls entry is given the name of a configuration entry, you can provide |
| 20 | +- `ca` - the server `ca` or `ca` chain (starting with the leaf certificate) |
| 21 | +- `cert` - the client certificate |
| 22 | +- `key` - the client certifcate key |
| 23 | +The data should be in PEM format. |
| 24 | + |
| 25 | +In our examples, we have two configuration: `selfsign` with a `ca` entry and `selfsignedmtls` with all three entries. |
| 26 | + |
| 27 | +TLS 1.2 and 1.3 are supported. TLS 1.0 and 1.1 are not supported. |
| 28 | + |
| 29 | +## Try it out! |
| 30 | + |
| 31 | +`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` |
| 32 | +During `stepzen deploy`, the `STEPZEN_SERVER_CRT` environment variable is expanded and the result will be a yaml that looks like: |
| 33 | +``` |
| 34 | +configurationset: |
| 35 | + - configuration: |
| 36 | + name: selfsign |
| 37 | + ca: | |
| 38 | + -----BEGIN CERTIFICATE----- |
| 39 | + MIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL |
| 40 | + ... |
| 41 | + -----END CERTIFICATE----- |
| 42 | +``` |
| 43 | + |
| 44 | +The `selfsignedmtls` configuration contains an example mutual TLS configuration. |
| 45 | + |
| 46 | +Two safe approaches are to set the environment variables from secrets or to have a `.env` file. |
| 47 | + |
| 48 | +See tricks below for some possible hurdles. |
| 49 | + |
| 50 | +### Running a test |
| 51 | + |
| 52 | +Testing mTLS or self-signed certificates locally is best done using local API Connect for GraphQL. |
| 53 | +In the following, we'll generate the certificates using openssl, use openssl to for trivialself-signed cert servers |
| 54 | +and use the stepzen cli local service mode as a client. |
| 55 | + |
| 56 | +Note: if you are not using Docker, see Tricks and hints/Container tools. |
| 57 | + |
| 58 | +#### Steps |
| 59 | +``` |
| 60 | +stepzen service start |
| 61 | +stepzen login --config ~/.stepzen/stepzen-config.local.yaml |
| 62 | +(cd tests; make env) |
| 63 | +# WARNING: if you are not using Docker, please see |
| 64 | +# Tricks and hints/Container tools |
| 65 | +stepzen deploy |
| 66 | +
|
| 67 | +# start trivial local TLS server using openssl |
| 68 | +# enable DEBUG if there are issues |
| 69 | +((cd tests; make run_validation_server_self_sign) & |
| 70 | +# wait until it gets establish 1-30s |
| 71 | +
|
| 72 | +# run the actual tests |
| 73 | +stepzen request -f operations.graphql |
| 74 | +
|
| 75 | +# cleanup |
| 76 | +stepzen service stop |
| 77 | +# restore your SaaS or other credentials |
| 78 | +``` |
| 79 | + |
| 80 | + |
| 81 | +## Tricks and hints |
| 82 | + |
| 83 | +### Container tools |
| 84 | + |
| 85 | +API Connect for GraphQL local services runs inside of a container using Docker, Podman, or other container runtime toolset. Each of these have a slightly different method whereby containers can access the host machine's localhost. The details of these are varied depending upon the actual toolset. |
| 86 | + |
| 87 | +By default, `rest_self` uses `host.docker.internal` which works in most modern Docker environments. |
| 88 | + |
| 89 | +For Podman, you may need to change this to `host.containers.internal` or `localhost` depending on your podman defaults. You may also need to modify your podman default configuration to allow for such access. |
| 90 | + |
| 91 | +### env variables |
| 92 | + |
| 93 | +You can set `STEPZEN_*` env variables in .env or using export. |
| 94 | + |
| 95 | +For example: |
| 96 | +``` |
| 97 | +export STEPZEN_SERVER_CRT=`cat server.pem` |
| 98 | +``` |
| 99 | +will set STEPZEN_SERVER_CRT to something like this: |
| 100 | +``` |
| 101 | +-----BEGIN CERTIFICATE-----\nMIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL\nBQA....\nEUhqWbTk+y13A1OPfWbJu82zTKfJFvCAUgCf -----END CERTIFICATE-----" |
| 102 | +``` |
| 103 | + |
| 104 | +Be aware that the `\n` will show up as spaces if you do echo $STEPZEN_SERVER_CRT |
| 105 | + |
| 106 | +To double check, you'll want to do something like this: |
| 107 | +``` |
| 108 | +cat <<EOF |
| 109 | +$STEPZEN_SERVER_CRT |
| 110 | +EOF |
| 111 | +``` |
| 112 | +or use techniques outlined in Misconfigured config.yaml below. |
| 113 | + |
| 114 | +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: |
| 115 | +``` |
| 116 | +STEPZEN_SERVER_CRT="-----BEGIN CERTIFICATE-----\nMIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL\n...\n-----END CERTIFICATE-----" |
| 117 | +``` |
| 118 | +or |
| 119 | +``` |
| 120 | +STEPZEN_SERVER_CRT="-----BEGIN CERTIFICATE----- |
| 121 | +MIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL |
| 122 | +... |
| 123 | +-----END CERTIFICATE-----" |
| 124 | +``` |
| 125 | + |
| 126 | + |
| 127 | +### Misconfigured config.yaml |
| 128 | + |
| 129 | +You can check if the config.yaml being uploaded by running |
| 130 | +``` |
| 131 | +DEBUG="stepzen:sdk:trace" stepzen deploy |
| 132 | +``` |
| 133 | +and looking for the configuration. Useful if the .env or exported variables are not |
| 134 | +as expected in the config.yaml or if you've directly placed the data in the `config.yaml` |
| 135 | +that it is as you expected. |
| 136 | + |
| 137 | +You are looking for something that looks like: |
| 138 | +``` |
| 139 | +"configuration":{"configurationset":[{"configuration":{"name":"selfsign","ca": |
| 140 | +"-----BEGIN CERTIFICATE-----\nMIIF5zCCA8+gAwIBAgIUS2BwtghuA7PREQ5AWzOeeT+tCe4wDQYJKoZIhvcNAQEL\nBQAwbTE... |
| 141 | +``` |
| 142 | +notice the '\n'. If you see spaces you've done something wrong upsteram. |
| 143 | + |
| 144 | + |
| 145 | +### Debugging |
| 146 | +You can debug using stepzen request by adding `-H "stepzen-debug-level: 1"` |
| 147 | +``` |
| 148 | + stepzen request '{rest_self}' -H "stepzen-debug-level: 1" |
| 149 | +``` |
| 150 | +and you can check the output for issues. You can check if tls values are being passed by looking for the tls |
| 151 | +block. In this case for mutual tls, we'll have: |
| 152 | +``` |
| 153 | + "tls": { |
| 154 | + "clientCertificate": { |
| 155 | + "keyPresent": true, |
| 156 | + "present": true |
| 157 | + }, |
| 158 | + "serverRootCA": { |
| 159 | + "present": true |
| 160 | + } |
| 161 | + }, |
| 162 | +``` |
0 commit comments