Skip to content

Commit 96b2aae

Browse files
authored
Merge pull request #97396 from wgabor0427/OSDOCS-15381
OSDOCS-15381 created oidc assembly and updated topic map
2 parents 88ecd78 + 04950a4 commit 96b2aae

12 files changed

+1365
-3
lines changed

_topic_maps/_topic_map.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,8 @@ Topics:
12311231
File: zero-trust-manager-install
12321232
- Name: Deploying Zero Trust Workload Identity Manager operands
12331233
File: zero-trust-manager-configuration
1234+
- Name: Configuring Zero Trust Workload Identity Manager OIDC Federation
1235+
File: zero-trust-manager-oidc-federation
12341236
- Name: Monitoring Zero Trust Workload Identity Manager
12351237
File: zero-trust-manager-monitoring
12361238
- Name: Enabling create-only mode for the Zero Trust Workload Identity Manager
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * security/zero_trust_workload_identity_manageer/zero-trust-manager-oidc-federation.adoc
4+
5+
:_mod-docs-content-type: CONCEPT
6+
[id="zero-trust-manager-config-vault-oidc_{context}"]
7+
= How to configure the Vault OpenID Connect
8+
9+
The Vault OpenID Connect (OIDC) allows a SPIRE-identified workload to authenticate against a federated Vault server. The SPIRE Server issues JSON Web Token SPIFFE Verifiable Identity Documents (JWT-SVIDs) to workloads and the workloads then present the JWT-SVID to Vault to authenticate and retrieve the secrets it is authorized to access.
10+
11+
The steps to configure Vault OIDC are:
12+
13+
* Install Vault
14+
15+
* Initialize Vault
16+
17+
18+
19+
Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * security/zero_trust_workload_identity_manageer/zero-trust-manager-oidc-federation.adoc
4+
5+
:_mod-docs-content-type: PROCEDURE
6+
[id="zero-trust-manager-configure-aws_{context}"]
7+
= Using Entra ID with {azure-first}
8+
9+
After the Entra ID configuration is complete, you can set up Entra ID to work with {azure-short}.
10+
11+
.Prerequisites
12+
13+
* You have configured the SPIRE OIDC Discovery Provider Route to serve the TLS certificates from a publicly trusted CA.
14+
15+
== Configuring an {azure-short} account
16+
17+
.Procedure
18+
19+
. Log in to Azure by running the following command:
20+
+
21+
[source,terminal]
22+
----
23+
$ az login
24+
----
25+
26+
. Configure variables for your Azure subscription and tenant:
27+
+
28+
[source,terminal]
29+
----
30+
$ export SUBSCRIPTION_ID=$(az account list --query "[?isDefault].id" -o tsv) <1>
31+
$ export TENANT_ID=$(az account list --query "[?isDefault].tenantId" -o tsv) <2>
32+
$ export LOCATION=centralus <3>
33+
----
34+
+
35+
<1> Your unique subscription identifier.
36+
<2> The ID for your Azure Active Directory instance.
37+
<3> The Azure region where your resource is created.
38+
39+
. Define resource variable names.
40+
+
41+
[source,terminal]
42+
----
43+
$ export NAME=ztwim <1>
44+
$ export RESOURCE_GROUP="${NAME}-rg" <2>
45+
$ export STORAGE_ACCOUNT="${NAME}storage" <3>
46+
$ export STORAGE_CONTAINER="${NAME}storagecontainer" <4>
47+
$ export USER_ASSIGNED_IDENTITY_NAME="${NAME}-identity" <5>
48+
----
49+
+
50+
<1> A base name for all resources.
51+
<2> The name of the resource group.
52+
<3> The name for the storage account.
53+
<4> The name for the storage container.
54+
<5> The name for a managed identity.
55+
56+
. Create the resource group.
57+
+
58+
[source,terminal]
59+
----
60+
$ az group create \
61+
--name "${RESOURCE_GROUP}" \
62+
--location "${LOCATION}"
63+
----
64+
65+
== Configuring Azure blob storage
66+
67+
.Procedure
68+
69+
. Create a new storage account that is used to store content.
70+
+
71+
[source,terminal]
72+
----
73+
$ az storage account create \
74+
--name ${STORAGE_ACCOUNT} \
75+
--resource-group ${RESOURCE_GROUP} \
76+
--location ${LOCATION} \
77+
--encryption-services blob
78+
----
79+
80+
. Obtain the storage ID for the newly created storage account.
81+
+
82+
[source,terminal]
83+
----
84+
$ export STORAGE_ACCOUNT_ID=$(az storage account show -n ${STORAGE_ACCOUNT} -g ${RESOURCE_GROUP} --query id --out tsv)
85+
----
86+
87+
. Create a storage container inside the newly created Storage Account to provide a location to support the storage of blobs.
88+
+
89+
[source,terminal]
90+
----
91+
$ az storage container create \
92+
--account-name ${STORAGE_ACCOUNT} \
93+
--name ${STORAGE_CONTAINER} \
94+
--auth-mode login
95+
----
96+
97+
== Configuring an Azure user managed identity
98+
99+
.Procedure
100+
101+
. Create a new User Managed Identity and then obtain the Client ID of the related Service Principal associated with the User Managed Identity.
102+
+
103+
[source,terminal]
104+
----
105+
$ az identity create \
106+
--name ${USER_ASSIGNED_IDENTITY_NAME} \
107+
--resource-group ${RESOURCE_GROUP}
108+
109+
$ export IDENTITY_CLIENT_ID=$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)
110+
----
111+
112+
. Associate a role with the Service Principal associated with the User Managed Identity.
113+
+
114+
[source,terminal]
115+
----
116+
$ az role assignment create \
117+
--role "Storage Blob Data Contributor" \
118+
--assignee "${IDENTITY_CLIENT_ID}" \
119+
--scope ${STORAGE_ACCOUNT_ID}
120+
----
121+
122+
== Creating the demonstration application
123+
124+
.Procedure
125+
126+
. Set the application name and namespace.
127+
+
128+
[source,terminal]
129+
----
130+
$ export APP_NAME=workload-app
131+
$ export APP_NAMESPACE=demo
132+
----
133+
134+
. Create the namespace.
135+
+
136+
[source,terminal]
137+
----
138+
$ oc create namespace $APP_NAMESPACE
139+
----
140+
141+
. Create the application Secret.
142+
+
143+
[source,terminal]
144+
----
145+
$ oc apply -f - << EOF
146+
apiVersion: v1
147+
kind: Secret
148+
metadata:
149+
name: $APP_NAME
150+
namespace: $APP_NAMESPACE
151+
stringData:
152+
AAD_AUTHORITY: https://login.microsoftonline.com/
153+
AZURE_AUDIENCE: "api://AzureADTokenExchange"
154+
AZURE_TENANT_ID: "${TENANT_ID}"
155+
AZURE_CLIENT_ID: "${IDENTITY_CLIENT_ID}"
156+
BLOB_STORE_ACCOUNT: "${STORAGE_ACCOUNT}"
157+
BLOB_STORE_CONTAINER: "${STORAGE_CONTAINER}"
158+
EOF
159+
----
160+
161+
== Deploying the workload application
162+
163+
.Procedure
164+
165+
. To deploy the application, copy the entire command block provided and paste it directly into your terminal. Press *Enter*.
166+
+
167+
[source,terminal]
168+
----
169+
$ oc apply -f - << EOF
170+
apiVersion: v1
171+
kind: ServiceAccount
172+
metadata:
173+
name: $APP_NAME
174+
namespace: $APP_NAMESPACE
175+
---
176+
kind: Deployment
177+
apiVersion: apps/v1
178+
metadata:
179+
name: $APP_NAME
180+
namespace: $APP_NAMESPACE
181+
spec:
182+
selector:
183+
matchLabels:
184+
app: $APP_NAME
185+
template:
186+
metadata:
187+
labels:
188+
app: $APP_NAME
189+
deployment: $APP_NAME
190+
spec:
191+
serviceAccountName: $APP_NAME
192+
containers:
193+
- name: $APP_NAME
194+
image: "registry.redhat.io/ubi9/python-311:latest"
195+
command:
196+
- /bin/bash
197+
- "-c"
198+
- |
199+
#!/bin/bash
200+
pip install spiffe azure-cli
201+
202+
cat << EOF > /opt/app-root/src/get-spiffe-token.py
203+
#!/opt/app-root/bin/python
204+
from spiffe import JwtSource
205+
import argparse
206+
parser = argparse.ArgumentParser(description='Retrieve SPIFFE Token.')
207+
parser.add_argument("-a", "--audience", help="The audience to include in the token", required=True)
208+
args = parser.parse_args()
209+
with JwtSource() as source:
210+
jwt_svid = source.fetch_svid(audience={args.audience})
211+
print(jwt_svid.token)
212+
EOF
213+
214+
chmod +x /opt/app-root/src/get-spiffe-token.py
215+
while true; do sleep 10; done
216+
envFrom:
217+
- secretRef:
218+
name: $APP_NAME
219+
env:
220+
- name: SPIFFE_ENDPOINT_SOCKET
221+
value: unix:///run/spire/sockets/spire-agent.sock
222+
securityContext:
223+
allowPrivilegeEscalation: false
224+
capabilities:
225+
drop:
226+
- ALL
227+
readOnlyRootFilesystem: false
228+
runAsNonRoot: true
229+
seccompProfile:
230+
type: RuntimeDefault
231+
ports:
232+
- containerPort: 8080
233+
protocol: TCP
234+
volumeMounts:
235+
- name: spiffe-workload-api
236+
mountPath: /run/spire/sockets
237+
readOnly: true
238+
volumes:
239+
- name: spiffe-workload-api
240+
csi:
241+
driver: csi.spiffe.io
242+
readOnly: true
243+
EOF
244+
----
245+
246+
.Verification
247+
. Ensure that the `workload-app` pod is running successfully.
248+
+
249+
[source,terminal]
250+
----
251+
$ oc get pods -n $APP_NAMESPACE
252+
----
253+
+
254+
.Example output
255+
[source, terminal]
256+
----
257+
NAME READY STATUS RESTARTS AGE
258+
workload-app-5f8b9d685b-abcde 1/1 Running 0 60s
259+
----
260+
261+
. Retrieve the SPIFFE JWT Token (SVID-JWT)
262+
+
263+
[source,terminal]
264+
----
265+
# Get the pod name dynamically
266+
$ POD_NAME=$(oc get pods -n $APP_NAMESPACE -l app=$APP_NAME -o jsonpath='{.items[0].metadata.name}')
267+
268+
# Execute the script inside the pod
269+
$ oc exec -it $POD_NAME -n $APP_NAMESPACE -- \
270+
/opt/app-root/src/get-spiffe-token.py -a "api://AzureADTokenExchange"
271+
----
272+
273+
== Configuring Azure with the SPIFFE identity federation
274+
275+
.Procedure
276+
277+
* Federate the identities between the User Managed Identity and the SPIFFE identity associated with the workload application.
278+
+
279+
[source,terminal]
280+
----
281+
$ az identity federated-credential create \
282+
--name ${NAME} \
283+
--identity-name ${USER_ASSIGNED_IDENTITY_NAME} \
284+
--resource-group ${RESOURCE_GROUP} \
285+
--issuer https://$JWT_ISSUER_ENDPOINT \
286+
--subject spiffe://$APP_DOMAIN/ns/$APP_NAMESPACE/sa/$APP_NAME \
287+
--audience api://AzureADTokenExchange
288+
----
289+
290+
== Verifying that the application workload can access the content in the Azure Blob Storage
291+
292+
.Procedure
293+
294+
. Retrieve a JWT token from the SPIFFE Workload API and login to the Azure CLI included within the pod.
295+
+
296+
[source,terminal]
297+
----
298+
$ oc rsh -n $APP_NAMESPACE deployment/$APP_NAME
299+
300+
$ export TOKEN=$(/opt/app-root/src/get-spiffe-token.py --audience=$AZURE_AUDIENCE)
301+
$ az login --service-principal \
302+
-t ${AZURE_TENANT_ID} \
303+
-u ${AZURE_CLIENT_ID} \
304+
--federated-token ${TOKEN}
305+
----
306+
307+
. Create a new file with the application workload pod and upload the file to the Blob Storage.
308+
+
309+
[source,terminal]
310+
----
311+
$ echo “Hello from OpenShift” > openshift-spire-federated-identities.txt
312+
$ az storage blob upload \
313+
--account-name ${BLOB_STORE_ACCOUNT} \
314+
--container-name ${BLOB_STORE_CONTAINER} \
315+
--name openshift-spire-federated-identities.txt \
316+
--file openshift-spire-federated-identities.txt \
317+
--auth-mode login
318+
----
319+
320+
.Verification
321+
* Confirm the file uploaded successfully by listing the files contained.
322+
+
323+
[source,terminal]
324+
----
325+
$ az storage blob list \
326+
--account-name ${BLOB_STORE_ACCOUNT} \
327+
--container-name ${BLOB_STORE_CONTAINER} \
328+
--auth-mode login \
329+
-o table
330+
----
331+

0 commit comments

Comments
 (0)