Page
Access AWS S3 from a sample application
Now that you have deployed SPIFFE/SPIRE to Red Hat OpenShift and created the necessary assets within the AWS cloud, the final step is to deploy a sample application to access the S3 bucket using the identity provided by SPIFFE/SPIRE.
In this lesson, you will:
- Deploy a sample application to access the S3 bucket using the identity provided by SPIFFE/SPIRE.
Set up a namespace and permissions
Create a namespace called demo for the sample application:
oc apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: null
name: demo
EOFThe SPIFFE Workload API is made available to applications using a CSI driver. Most OpenShift environments use the restricted-v2 security context constraint (SCC) by default. Apply the following policies only when running in IBM Cloud to enable the workload to access the restricted-v2 SCC.
oc apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: system:openshift:scc:restricted-v2-csi
rules:
- apiGroups:
- security.openshift.io
resourceNames:
- restricted-v2-csi
resources:
- securitycontextconstraints
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: system:openshift:scc:restricted-v2-csi
namespace: demo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:openshift:scc:restricted-v2-csi
subjects:
- kind: ServiceAccount
name: demo
namespace: demo
EOFDeploy the sample application
Note: This section requires the following environment variables, defined above:
ROLE_ARNS3_BUCKET
Finally, apply the following to create a service account called demo and deploy the sample application:
oc apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: demo
namespace: demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
namespace: demo
labels:
app: demo
spec:
replicas: 1
selector:
matchLabels:
app: demo
template:
metadata:
labels:
identity_template: "true"
app: demo
spec:
hostPID: false
hostNetwork: false
dnsPolicy: ClusterFirstWithHostNet
serviceAccountName: demo
containers:
- name: demo
image: docker.io/tsidentity/spire-demo:latest
env:
- name: SPIFFE_ENDPOINT_SOCKET
value: "/spiffe-workload-api/spire-agent.sock"
- name: AWS_ROLE_ARN
value: "${ROLE_ARN}"
- name: S3_AUD
value: "mys3"
- name: "S3_CMD"
value: "aws s3 cp s3://${S3_BUCKET}/test -"
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: "/tmp/token.jwt"
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
volumeMounts:
- name: spiffe-workload-api
mountPath: /spiffe-workload-api
- name: empty
mountPath: /.aws
volumes:
- name: spiffe-workload-api
csi:
driver: "csi.spiffe.io"
readOnly: true
- name: empty
emptyDir: {}
EOFConfirm that the application is running within the demo namespace.
# Obtain a list of pods in the demo namespace
oc get pods -n demoRerun the command until a pod with a Running status is achieved.
This demo image contains everything you need to execute the demo, including the AWS client, SPIRE client, and also a demoscript for automating the demo. The image for the demo container can be found in this repository.
All the demo variables including the S3 bucket location and the IAM access role are passed as container environmental variables.
Execute the workload
Obtain a shell session in the running demo pod:
oc -n demo rsh deployment/demoThis container has a nice demoscript that bootstraps all the required commands for you based on the environment variables injected within the container. To run the script, just type:
demo-s3.sh Move through the demo by continuing to press the space bar. The result should look similar to the following:
$ /opt/spire/bin/spire-agent api fetch jwt -audience mys3 -socketPath /spiffe-workload-api/spire-agent.sock
token(spiffe://mc-ztna-04-9d995c4a8c7c5f281ce13d5467ff6a94-0000.us-east.containers.appdomain.cloud/ns/demo/sa/demo):
eyJhbGciOiJSUzI1NiIsImtpZCI6ImxCRXl0d05MMkpibWxGa1JIaHUybzFoTHFxVEtnWWVDIiwidHlwIjoiSl
. . . .
$ /opt/spire/bin/spire-agent api fetch jwt -audience mys3 -socketPath /spiffe-workload-api/spire-agent.sock | sed -n '2p' | xargs > /tmp/token.jwt
$ AWS_ROLE_ARN=arn:aws:iam::203747186855:role/role-mc-ztna-demo AWS_WEB_IDENTITY_TOKEN_FILE=/tmp/token.jwt aws s3 cp s3://mc-ztna-demo/test -
my secret messageSo, what did the demo script illustrate?
First, the
spire-agentCLI was utilized to obtain a JWT token from the workload API. The workload API is served via the CSI driver and mounted within the container at/spiffe-workload-api/spire-agent.sock.Then two environment variables (
AWS_ROLE_ARNandAWS_WEB_IDENTITY_TOKEN_FILE) are set based on an injected environment variable and a file representing the output of the obtained JWT token.Finally, the file stored in the AWS S3 bucket is retrieved and then contents are printed to the screen, verifying that we were able to access the content using the SPIFFE/SPIRE framework.
For more information about the demo application, please refer to the following article.
Clean up
To remove the resources that were created as part of this use case, utilize the steps included in the following sections:
AWS clean up
The section describes commands to clean up resources created in the AWS provider.
Note: This section requires the following environment variables, defined above:
OIDC_SERVERS3_BUCKET
aws s3 rb s3://$S3_BUCKET --forceaws iam delete-role-policy --role-name role-$S3_BUCKET --policy-name policy-$S3_BUCKETaws iam delete-role --role-name role-$S3_BUCKETexport OIDC_ARN=`aws iam list-open-id-connect-providers --output=json | jq '.OpenIDConnectProviderList[].Arn' | grep $OIDC_SERVER | tr -d '"'`aws iam delete-open-id-connect-provider --open-id-connect-provider-arn $OIDC_ARNOpenShift clean up
kubectl -n demo delete deploy demokubectl -n demo delete sa demokubectl delete ns demohelm --namespace spire-server uninstall spirehelm --namespace spire-server uninstall spire-crdskubectl delete ns spire-server Summary
This learning path demonstrated a simple use case of cross-cloud access using SPIRE. In future lessons, we will demonstrate more complex use cases, such as communication between services across multiple public and on-prem cloud platforms. These use cases leverage SPIRE capabilities such as nesting and federation for scaling across clouds. We will also demonstrate how SPIRE integrates with Sigstore and provides identities to the worker nodes that are used for signing and deploying images within a trusted software supply chain framework.
Ready to learn more? Read this developer e-book: Build a Foundation of security with Zero Trust and automation