blob: 3afd6fdd53e675171f9cd6b2524b286d921d0808 [file] [log] [blame]
Mohammed Naserc0ba6662025-01-29 16:39:41 -05001##############
2Authentication
3##############
4
5*******************************************
6Using external token from identity provider
7*******************************************
8
9Since OpenStack is configured to trust Keycloak as an identity provider, you will
10need to generate a token from Keycloak and use it to authenticate with the OpenStack
11API.
12
13If you are using Keycloak with an OpenID Connect (OIDC) identity provider, you
14may want to exchange a token generated from your identity provider for a token
15from Keycloak, which can then be used to authenticate with the OpenStack API.
16
17.. mermaid::
18 :align: center
19 :config: {"theme": "dark"}
20
21 sequenceDiagram
22 participant Client
23 participant OIDC Provider
24 participant Keycloak
25 participant Keystone
26 participant OpenStack
27
28 Client->>OIDC Provider: Request Token (Client Credentials)
29 OIDC Provider-->>Client: Returns OIDC Token
30
31 Client->>Keycloak: Exchange OIDC Token
32 Keycloak-->>Client: Returns Keycloak OIDC Token
33
34 Client->>Keystone: Authenticate with Keycloak Token
35 Keystone-->>Client: Returns Keystone Token
36
37 Client->>OpenStack: Use Keystone Token
38 OpenStack-->>Client: OpenStack API Access Granted
39
40In order to get started with this process, you'll need a OpenID connect token
41issued by an identity provider which exists in the Keycloak realm.
42
431. **Exchange the OpenID connect (OIDC) Token with Keycloak**
44
45 Use the *OpenID connect token* from your identity provider and exchange it for
46 a *Keycloak-issued token*. The following ``curl`` command is provided as an
47 example but you can use any tool that can make HTTP requests.
48
49 You will need to replace the following placeholders in the example code:
50
51 - ``<KEYCLOAK_URL>``: The URL of your Keycloak instance.
52 - ``<KEYCLOAK_CLIENT_ID>``: The client ID of the Keycloak client.
53 - ``<KEYCLOAK_CLIENT_SECRET>``: The client secret of the Keycloak client.
54
55 .. code-block:: sh
56
57 curl -X POST "https://<KEYCLOAK_URL>/realms/atmosphere/protocol/openid-connect/token" \
58 -H "Content-Type: application/x-www-form-urlencoded" \
59 -d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
60 -d "client_id=<KEYCLOAK_CLIENT_ID>" \
61 -d "client_secret=<KEYCLOAK_CLIENT_SECRET>" \
62 -d "subject_token=<OIDC_TOKEN>" \
63 -d "subject_token_type=urn:ietf:params:oauth:token-type:access_token"
64
65 The response will return a token that is issued by Keycloak which you can use
66 to authenticate with the OpenStack API.
67
68 .. code-block:: json
69
70 {
71 "access_token" : ".....",
72 "refresh_token" : ".....",
73 "expires_in" : "...."
74 }
75
76
772. **Authenticate with Keystone Using the Keycloak Token**
78
79 With the token issued by Keycloak, you can now authenticate with Keystone in order
80 to obtain a fernet token which can be used to talk to all of the OpenStack APIs.
81
82 You will need to replace the following placeholders in the example code:
83
84 - ``<OPENSTACK_AUTH_URL>``: The URL of your Keystone authentication endpoint.
85 - ``<KEYCLOAK_OIDC_TOKEN>``: The token issued by Keycloak.
86
87 .. code-block:: sh
88
89 curl "<OPENSTACK_AUTH_URL>/v3/OS-FEDERATION/identity_providers/atmosphere/protocols/openid/auth" \
90 -H "Authorization: Bearer <KEYCLOAK_OIDC_TOKEN>"
91
92 This response will return an unscoped Keystone token (not tied to any project) which
93 will be in the ``X-Subject-Token`` header.
94
95 .. code-block:: http
96
97 HTTP/1.1 201 Created
98 X-Subject-Token: <UNSCOPED_KEYSTONE_TOKEN>
99
1003. **List projects using the Keystone Token** (optional, if you already know the project ID)
101
102 At this point, you have an unscoped token issued by Keystone which is not bound
103 to any project. You will need to exchange that token for a project-scoped token
104 in order to be able to interact with the OpenStack APIs.
105
106 You can choose to list what projects you have access to using the Keystone token
107 that you have obtained.
108
109 You will need to replace the following placeholders in the example code:
110
111 - ``<OPENSTACK_AUTH_URL>``: The URL of your Keystone authentication endpoint.
112 - ``<UNSCOPED_KEYSTONE_TOKEN>``: The token issued by Keystone.
113
114 .. code-block:: sh
115
116 curl "<OPENSTACK_AUTH_URL>/v3/projects" \
117 -H "X-Auth-Token: <UNSCOPED_KEYSTONE_TOKEN>"
118
119 This response will return a list of projects that you have access to.
120
121 .. code-block:: json
122
123 {
124 "projects": [
125 {
126 "id": "....",
127 "name": "....",
128 "description": "...."
129 }
130 ]
131 }
132
1334. **Exchange the unscoped token for a project-scoped token**
134
135 Once you have identified the project that you want to interact with, you can
136 exchange the unscoped token for a project-scoped token.
137
138 You will need to replace the following placeholders in the example code:
139
140 - ``<OPENSTACK_AUTH_URL>``: The URL of your Keystone authentication endpoint.
141 - ``<UNSCOPED_KEYSTONE_TOKEN>``: The token issued by Keystone.
142 - ``<PROJECT_ID>``: The ID of the project that you want to interact with.
143
144 .. code-block:: sh
145
146 curl "<OPENSTACK_AUTH_URL>/v3/auth/projects" \
147 -H "Content-Type: application/json" \
148 -H "X-Auth-Token: <UNSCOPED_KEYSTONE_TOKEN>" \
149 -d '{
150 "auth": {
151 "identity": {
152 "methods": ["token"],
153 "token": {
154 "id": "<UNSCOPED_KEYSTONE_TOKEN>"
155 }
156 },
157 "scope": {
158 "project": {
159 "id": "<PROJECT_ID>"
160 }
161 }
162 }
163 }'
164
165 This response will return a project-scoped token which you can use to interact
166 with the OpenStack APIs which will be in the ``X-Subject-Token`` header.
167
168 .. code-block:: http
169
170 HTTP/1.1 201 Created
171 X-Subject-Token: <SCOPED_KEYSTONE_TOKEN>
172
173 OpenStack Keystone will provide the token details in the response body, including
174 the full catalog of services that you have access to.
175
176 .. code-block:: json
177
178 {
179 "token": {
180 "methods": [
181 "token"
182 ],
183 "expires_at": "....",
184 "issued_at": "....",
185 "user": {
186 "domain": {
187 "id": "....",
188 "name": "...."
189 },
190 "id": "....",
191 "name": "...."
192 },
193 "audit_ids": [
194 "...."
195 ],
196 "catalog": [
197 {
198 "endpoints": [
199 {
200 "id": "....",
201 "interface": "....",
202 "region": "....",
203 "url": "...."
204 }
205 ],
206 "id": "....",
207 "name": "....",
208 "type": "...."
209 }
210 ],
211 "project": {
212 "domain": {
213 "id": "....",
214 "name": "...."
215 },
216 "id": "....",
217 "name": "...."
218 }
219 }
220 }
221
222 You can then use the project-scoped token to interact with the OpenStack APIs,
223 such as creating a server, listing servers, etc.