Skip to content

Commit 1ca5cb4

Browse files
feat: Add support for authentication with provided Keycloak Access Token (#1320)
- Allow users to use a provided access token for authentication - Add test for authenticating with provided access token - Add target to generate a current acces-token to the makefile - Update github ci tests to support - Add docs Fixes #1319 Signed-off-by: Thomas Darimont <[email protected]> Co-authored-by: Christopher Svensson <[email protected]>
1 parent 04cb433 commit 1ca5cb4

File tree

10 files changed

+247
-142
lines changed

10 files changed

+247
-142
lines changed

.github/workflows/test.yml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,12 @@ jobs:
149149

150150
timeout-minutes: 60
151151
# Only run mtls test for the later versions
152-
- name: Test (mtls client auth)
152+
- name: Test (auth with mtls client certificate)
153153
if: matrix.keycloak-version == '26.3.4' || matrix.keycloak-version == '26.2.5'
154154
run: |
155155
terraform version
156156
go mod download
157-
make testacc
157+
make testauth
158158
env:
159159
KEYCLOAK_CLIENT_ID: terraform
160160
KEYCLOAK_CLIENT_SECRET: 884e0f95-0f42-4a63-9b1f-94274655669e
@@ -171,6 +171,23 @@ jobs:
171171

172172
timeout-minutes: 60
173173

174+
- name: Test (auth with provided access token)
175+
if: matrix.keycloak-version == '26.3.4' || matrix.keycloak-version == '26.2.5'
176+
run: |
177+
terraform version
178+
go mod download
179+
make access-token
180+
export KEYCLOAK_ACCESS_TOKEN="$(cat ./keycloak_access_token)"
181+
make testauth
182+
env:
183+
KEYCLOAK_CLIENT_ID: terraform
184+
KEYCLOAK_CLIENT_TIMEOUT: 120
185+
KEYCLOAK_REALM: master
186+
KEYCLOAK_URL: "http://localhost:8080"
187+
KEYCLOAK_VERSION: ${{ steps.keycloak-version.outputs.result }}
188+
189+
timeout-minutes: 60
190+
174191
- name: Print container logs
175192
if: always()
176193
run: docker logs keycloak

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ site/
3636
# releases
3737
*.zip
3838

39+
# Keycloak access token
40+
keycloak_access_token
41+
3942
.DS_Store
4043

4144
# Custom test_env overrides

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ KEYCLOAK_TLS_CA_CERT="$(cat provider/testdata/tls/server-cert.pem)" \
145145
make testacc
146146
```
147147

148-
#### Test with HTTPS + mTLS
148+
#### Test Authenticating with HTTPS + mTLS
149149
You can also run the same tests on Keycloak's https port with the Keycloak Terraform provider authenticating to the server with a mTLS client certificate.
150150
For this start the env with `make local-mtls`. After that run the following command:
151151

@@ -160,7 +160,24 @@ KEYCLOAK_URL="https://localhost:8443" \
160160
KEYCLOAK_TLS_CLIENT_CERT="$(cat provider/testdata/tls/client-cert.pem)" \
161161
KEYCLOAK_TLS_CLIENT_KEY="$(cat provider/testdata/tls/client-key.pem)" \
162162
KEYCLOAK_TLS_CA_CERT="$(cat provider/testdata/tls/server-cert.pem)" \
163-
make testacc
163+
make testauth
164+
```
165+
166+
#### Test Authenticating with provided Access Token
167+
You can also run the same test with a provided access token.
168+
For this start the env with `make local`. To obtain an access token for the admin user via the admin-cli client, run `make access-token` to
169+
store an acess token in the `./keycloak_access_token` file.
170+
171+
After that run the following command:
172+
173+
```
174+
make access-token
175+
KEYCLOAK_CLIENT_ID=terraform \
176+
KEYCLOAK_CLIENT_TIMEOUT=5 \
177+
KEYCLOAK_ACCESS_TOKEN="$(cat keycloak_access_token)" \
178+
KEYCLOAK_REALM=master \
179+
KEYCLOAK_URL="http://localhost:8080" \
180+
make testauth
164181
```
165182

166183
### Run examples

docs/index.md

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,17 @@ account within the `foo` realm.
6363
the realm clients to a user or service account within the `master` realm. For example, given a Keycloak instance with realms
6464
`master`, `foo`, and `bar`, assign the `create-client` client role from the clients `master-realm`, `foo-realm`, and `bar-realm`.
6565

66-
## Example Usage (client credentials grant - client secret)
66+
## Authentication
67+
68+
The Terraform Provider currently supports the following authentication methods:
69+
- Client-Credentials Grant (client_id + client_secret)
70+
- Password Grant (client_id (+client_secret), username, password)
71+
- Signed JWT (Private Key JWT)
72+
- Provided Access Token (pre-provisioned Keycloak Access Token)
73+
74+
Additionally, the Terraform Provider also supports using an mTLS client certificate to access Keycloak.
75+
76+
### Example Usage (client credentials grant - client secret)
6777

6878
```hcl
6979
provider "keycloak" {
@@ -73,7 +83,7 @@ provider "keycloak" {
7383
}
7484
```
7585

76-
## Example Usage (client credentials grant - private key signed JWT)
86+
### Example Usage (client credentials grant - private key signed JWT)
7787

7888
```hcl
7989
provider "keycloak" {
@@ -83,7 +93,7 @@ provider "keycloak" {
8393
}
8494
```
8595

86-
## Example Usage (password grant)
96+
### Example Usage (password grant)
8797

8898
```hcl
8999
provider "keycloak" {
@@ -94,6 +104,29 @@ provider "keycloak" {
94104
}
95105
```
96106

107+
### Example Usage (provided Token)
108+
109+
```hcl
110+
provider "keycloak" {
111+
client_id = "admin-cli"
112+
access_token = "<encoded-access-token-here>"
113+
url = "http://localhost:8080"
114+
}
115+
```
116+
117+
### Example Usage (mTLS Certificate)
118+
```hcl
119+
provider "keycloak" {
120+
client_id = "terraform"
121+
client_secret = "884e0f95-0f42-4a63-9b1f-94274655669e"
122+
jwt_signing_key = "<pem-formatted-private-key>"
123+
tls_client_certificate = "<pem-formatted-client-certificate>"
124+
tls_client_private_key = "<pem-formatted-client-key>"
125+
root_ca_certificate = "<pem-formatted-server-certificate>"
126+
url = "https://localhost:8443"
127+
}
128+
```
129+
97130
## Argument Reference
98131

99132
The following arguments are supported:
@@ -104,6 +137,7 @@ The following arguments are supported:
104137
- `client_secret` - (Optional) The secret for the client used by the provider for authentication via the client credentials grant. This can be found or changed using the "Credentials" tab in the client settings. Defaults to the environment variable `KEYCLOAK_CLIENT_SECRET`. This attribute is required when using the client credentials grant, and cannot be set when using the password grant.
105138
- `username` - (Optional) The username of the user used by the provider for authentication via the password grant. Defaults to the environment variable `KEYCLOAK_USER`. This attribute is required when using the password grant, and cannot be set when using the client credentials grant.
106139
- `password` - (Optional) The password of the user used by the provider for authentication via the password grant. Defaults to the environment variable `KEYCLOAK_PASSWORD`. This attribute is required when using the password grant, and cannot be set when using the client credentials grant.
140+
- `access_token` - (Optional) The access token that should be used by the provider for authentication via token. Defaults to the environment variable `KEYCLOAK_ACCESS_TOKEN`.
107141
- `jwt_signing_key` - (Optional) The PEM-formatted private key used by provider to generate a signed JWT for authentication.
108142
- `jwt_signing_alg` - (Optional) The signing algorithm used by provider to generate a signed JWT for authentication. Defaults to `RS256`.
109143
- `realm` - (Optional) The realm used by the provider for authentication. Defaults to the environment variable `KEYCLOAK_REALM`, or `master` if the environment variable is not specified.

helper/helpers.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,34 @@ import (
55
"fmt"
66
"log"
77
"os"
8+
"testing"
89
)
910

11+
var requiredEnvironmentVariables = []string{
12+
"KEYCLOAK_CLIENT_ID",
13+
"KEYCLOAK_URL",
14+
"KEYCLOAK_REALM",
15+
}
16+
17+
var requiredEnvironmentVariablesForTokenAuth = []string{
18+
"KEYCLOAK_REALM",
19+
"KEYCLOAK_URL",
20+
}
21+
22+
func CheckRequiredEnvironmentVariables(t *testing.T) {
23+
24+
requiredEnvVars := requiredEnvironmentVariables
25+
if os.Getenv("KEYCLOAK_ACCESS_TOKEN") != "" {
26+
requiredEnvVars = requiredEnvironmentVariablesForTokenAuth
27+
}
28+
29+
for _, requiredEnvironmentVariable := range requiredEnvVars {
30+
if value := os.Getenv(requiredEnvironmentVariable); value == "" {
31+
t.Fatalf("%s must be set before running acceptance tests.", requiredEnvironmentVariable)
32+
}
33+
}
34+
}
35+
1036
func UpdateEnvFromTestEnvIfPresent() {
1137

1238
testEnvFile := os.Getenv("TEST_ENV_FILE")

0 commit comments

Comments
 (0)