-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Step and Sidecar Workspaces feature
Access to Workspaces can now be limited to specific Steps and Sidecars in a Task. This allows Task authors to isolate sensitive data to specific images, reducing exposure of assets like credentials. As a side-effect of this change Workspaces are now mounted to Sidecars by default, just as they are to Steps.
- Loading branch information
1 parent
565c55b
commit 98aef3b
Showing
20 changed files
with
1,337 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
examples/v1beta1/pipelineruns/alpha/isolated-workspaces.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# In this example a PipelineRun accepts a workspace | ||
# to use as ssh credentials. The PipelineTask | ||
# is configured so that only one of its Steps has access | ||
# to those creds. | ||
kind: Secret | ||
apiVersion: v1 | ||
metadata: | ||
name: test-ssh-credentials | ||
stringData: | ||
id_rsa: | | ||
-----BEGIN OPENSSH PRIVATE KEY----- | ||
abcdefghijklmnopqrstuvwxy1234567890 | ||
-----END OPENSSH PRIVATE KEY----- | ||
--- | ||
kind: PipelineRun | ||
apiVersion: tekton.dev/v1beta1 | ||
metadata: | ||
generateName: isolated-workspaces- | ||
spec: | ||
timeout: 60s | ||
workspaces: | ||
- name: ssh-credentials | ||
secret: | ||
secretName: test-ssh-credentials | ||
|
||
pipelineSpec: | ||
workspaces: | ||
- name: ssh-credentials | ||
|
||
tasks: | ||
- name: test-isolation | ||
workspaces: | ||
- name: creds | ||
workspace: ssh-credentials | ||
taskSpec: | ||
workspaces: | ||
- name: creds | ||
steps: | ||
- image: alpine:3.12.0 | ||
script: | | ||
if [ ! -d /creds ] ; then | ||
echo "unable to access creds" | ||
exit 1 | ||
fi | ||
workspaces: | ||
- name: creds | ||
mountpath: /creds | ||
- image: alpine:3.12.0 | ||
script: | | ||
if [ -d /workspace/creds ] ; then | ||
echo "this step should not be able to see creds" | ||
exit 255 | ||
fi |
201 changes: 201 additions & 0 deletions
201
examples/v1beta1/taskruns/alpha/authenticating-git-commands.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
# This example demonstrates usage of creds-init credentials to issue | ||
# git commands without a Git PipelineResource or git-clone catalog task. | ||
# | ||
# In order to exercise creds-init a sidecar is used to run a | ||
# git server fronted by SSH. The sidecar does the following things: | ||
# - Generates a host key pair, providing the public key to Steps for their known_hosts file | ||
# - Accepts a public key generated from creds-init credentials and uses that for an authorized_keys file | ||
# - Creates a bare git repo for the test git commands to run against | ||
# - Starts sshd and tails its log, waiting for the git commands to come in over SSH | ||
# | ||
# Two separate Steps then perform authenticated git actions against the sidecar | ||
# git server using the credentials mounted by Tekton's credential helper | ||
# (aka "creds-init"): | ||
|
||
# The first step makes a git clone of the bare repository and populates it | ||
# with a file. | ||
# | ||
# The second step makes a git clone of the populated repository and checks | ||
# the contents of the repo match expectations. This step runs as a non-root | ||
# user in order to exercise creds-init credentials when a securityContext | ||
# is set. | ||
# | ||
# Notice that in each Step there is different code for handling creds-init | ||
# credentials when the disable-home-env-overwrite flag is "false" and when | ||
# it's "true". | ||
apiVersion: v1 | ||
kind: Secret | ||
type: kubernetes.io/ssh-auth | ||
metadata: | ||
name: ssh-key-for-git | ||
annotations: | ||
tekton.dev/git-0: localhost | ||
data: | ||
# This key was generated for this test and isn't used for anything else. | ||
ssh-privatekey: LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUJsd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFZRUF5T1g3ZG5OWlFBZVk4cHNMOXlaUnp3NXNDVG1yWGh6Zld1YTZuZ2VDQ0VRRTY4YjVUSThTCkNlbEhlNG9oTUtBdXZ0ZTE4YXJMK2EvVldpeFN6a2tBMmFIZVhkdUJ1bStkS2R2TlVVSUhNc1dOUythcENQYmE4R3ZGaHYKdG81Tkx0bWpxT2M0WjJkK1RPS3AvakMrS3pvUDFHQWdRL25QMitMTldabzlvTTc4TzQ3Z1dSem9FNlFKeGJqbFlPMHRMbwp4YXUxdTNrbUtsNSthbUxsNHpGN25wdmV1dGlSWDhmY2hGam5Ka2dqK3BVeFJvTGF4SDdDN0NTcDExWUkyMEhKRVFXeEk3CllaekNTYml5KzZ1a2l0Tk1MZ29qMnpSTGl2ZTVvZm9nenpYbkdWUUpZdUIzOFhQM0ZIQWMvOXhzUXdzd3dQS2hkQ3g4T0QKbjErYXpLOHp5SGhXK0dxckJhS1R4cDlrcVRpKzZSMWk4ZjVxOEt6NXpGVTZmd05qQXZ3STFBZ3IwS2FzU1JxWTVMcGxnTgpZcW1DY01JODZKUnRGWHRWWVQrT05tdWFhYUQ1QUErbnpkNW81R0haZTlFSlNqUThZMHZwbjhmNjNjeEw2RTdzVmxpMnpzCnNhN1RST2JMK3YyVnFuSlpEY2pIZXMzS1M5Mld0V3RJbXdXOG81VkRBQUFGaU04K0NUL1BQZ2svQUFBQUIzTnphQzF5YzIKRUFBQUdCQU1qbCszWnpXVUFIbVBLYkMvY21VYzhPYkFrNXExNGMzMXJtdXA0SGdnaEVCT3ZHK1V5UEVnbnBSM3VLSVRDZwpMcjdYdGZHcXkvbXYxVm9zVXM1SkFObWgzbDNiZ2Jwdm5TbmJ6VkZDQnpMRmpVdm1xUWoyMnZCcnhZYjdhT1RTN1pvNmpuCk9HZG5ma3ppcWY0d3ZpczZEOVJnSUVQNXo5dml6Vm1hUGFETy9EdU80RmtjNkJPa0NjVzQ1V0R0TFM2TVdydGJ0NUppcGUKZm1waTVlTXhlNTZiM3JyWWtWL0gzSVJZNXlaSUkvcVZNVWFDMnNSK3d1d2txZGRXQ050QnlSRUZzU08yR2N3a200c3Z1cgpwSXJUVEM0S0k5czBTNHIzdWFINklNODE1eGxVQ1dMZ2QvRno5eFJ3SFAvY2JFTUxNTUR5b1hRc2ZEZzU5Zm1zeXZNOGg0ClZ2aHFxd1dpazhhZlpLazR2dWtkWXZIK2F2Q3MrY3hWT244RFl3TDhDTlFJSzlDbXJFa2FtT1M2WllEV0twZ25EQ1BPaVUKYlJWN1ZXRS9qalpybW1tZytRQVBwODNlYU9SaDJYdlJDVW8wUEdOTDZaL0grdDNNUytoTzdGWll0czdMR3UwMFRteS9yOQpsYXB5V1EzSXgzck55a3ZkbHJWclNKc0Z2S09WUXdBQUFBTUJBQUVBQUFHQUNQSGtmbU9vWjZkdThlNWhYQUhDeHJ0WHFCCmwvUGROL1JtYmJqRW05U216czR5cWEwd1BUdzhrMU81VHM0V05nY1hMZFVRTlB6YkE4aWFWTGtvL0JqKzhiSFlhMmdmeVMKUE5qaWpXbXBOR09EWlF2Q0h2b095WUdpNjkycHovWnNTZCt0bEFzNm54LzY1ZjcwZHdVREJub0FjZnFLY28wQnVMRlNBKworamY5RnhISGYzQkFEUS9TdDVFQjlZelo1Q2F2cTRQcjZvS2w3R3RpbnRIbTZIbUlwTUlubWVEMnV3cjl2ZGZ1RGJhVDdYClVOSm10elVGck1uOUhlOWd1WkoyTXd3a015S09ScnRhVFA3VjFZK3FOM3ZncStmRkNtU0VkekxBU3BWTHMyL1hQTCtwTnAKTTVZUVRRMFJSZWdKTEdtTHZ0ZmpkK1RRMFQ0bjBucnBJVGRXRTRsL05sTG9taTVhUndzQXFtY2hZSGxhN0g3YlNyS2lKawpyWTg1RTliZm8wSXJqUDNQNzFYNmxjcTB0VDhDTklUQUNleWJQT3kwcDVDc3JwZTdhZEJBOXF4MTZjR2tkZ0NPWk9GMnRpCktoWWJHeTc4ei9YNEh2OEptVmhaSHF3RlFQQzVleWljbE1PTFJXNDJOcUJhNEVFc3RHT3l4MHZwa0lVS3VhRlJuQkFBQUEKd1FESytXYzU1WHVpWjgySXM5NnN2bWIrR0Y5c2pBRWVaWHpHSWpDL1NHVEhIWTZSQmc1TnlQOUdZNmtoWnBjd0cyTU52dQpZUjhuN0psRWlVanU2cjY2Smh0WGtvdTR4WlU1dDkvMlJvdHRmeWpKODJmYm8yTHZmNERUOVNvSURxZnk5VmlMSjhSWUNkCkt6NnpYSHFTZ1RBRU1vaUhjbFpIZzRqTitrOW1ma2tPMDBQbEJJaE1YU0ZMLzUrZUhGdStQTmxaU1g5NUlMRjJvZ0Y1RG0KWTFuaTRUOGJjdzY2dmFzamthcjFZekptM1VidEVnSzQ2VVllNGJac2NXbWt4dngwMEFBQURCQVA4UysyTmtheWkvb3NzVApTQXpJMi9QU2tJMDVEY1lTYnNOQjZ4a3pobzdKaDlHeUNvbW5xZ1IxR2ZBOTBqV3AxVks0TG43TmtYYWJaVmJPc0xoT21DCkdBbVRZTHRjaTB0bkhhYk5HTEZ3ZmdiUitqRzZNQ2p4cEh5anM5MDlKSHhtYmswbElpczdPN1N3VThERGcrSEVxc0EvNUoKQ1VMTWU3em9mNERhUnZXdFhTRks2ZW5LNnpGaHBINjVQY29TN0o0NjJhNzdUMDVGQXhMemNaRkc5VWZ5WUdMa1ZmdHRTTApNVDhudW9LaW5XTGNLSlVQeis1MjJlM3lIcis4c3pVUUFBQU1FQXlhQ28xSnRBcjRpczY0YTBuZTFUV0o0dXcyT3FDdUlDCm9acG1QN2UyRnh3bVRCSWMrbzZkSEVNVHo2c2ZZSkFxU2l4ZzYydXYzWlRTc25STWljaDZ0b1k0SVI4cWFMa1prLzU5cmEKQWFONFlvTkdpQTZxY0Jzc3NLMmZuM2YxRFJhckxPbWZHTnpTMU41S1RvSFVlUkVGWDExdHVNM1pqOGxTelFBOWZSakk1OQpFWmFnOWJaOXRJOEg5dmEvTGRMK3U3dTZZWkVRSEJCS1MxMW1tOVVXd1pDMkdUV3ZnNzRlTnRmemtZeDQxdlhIeTZBbW9ECmxuOHo2N3lvWEZzbEpUQUFBQURuTmpiM1IwUUcxbFkyZ3ViR0Z1QVFJREJBPT0KLS0tLS1FTkQgT1BFTlNTSCBQUklWQVRFIEtFWS0tLS0tCg== | ||
# Note: we intentionally omit a known_hosts entry here. You should include | ||
# one in your own Secrets as a security measure, otherwise the Git PipelineResource | ||
# and git-clone Tasks will blindly accept any public key returned by a repository. | ||
# | ||
# We're able to omit known_hosts here because the file is generated by the | ||
# git server sidecar. The benefit of omitting it here is that it exercises | ||
# a codepath in Tekton that used to fail. In prior versions Tekton would | ||
# run ssh-keyscan if known_hosts was omitted, which would fail for this example | ||
# because the git server sidecar is not up and running at the time the scan | ||
# would have happened. | ||
--- | ||
apiVersion: v1 | ||
kind: ServiceAccount | ||
metadata: | ||
name: ssh-key-service-account | ||
secrets: | ||
- name: ssh-key-for-git | ||
--- | ||
apiVersion: tekton.dev/v1beta1 | ||
kind: TaskRun | ||
metadata: | ||
name: authenticating-git-commands | ||
spec: | ||
serviceAccountName: ssh-key-service-account | ||
workspaces: | ||
- name: messages | ||
emptyDir: {} | ||
taskSpec: | ||
workspaces: | ||
# Both the Steps and Sidecar will receive this workspace. | ||
- name: messages | ||
mountPath: /messages | ||
sidecars: | ||
- name: server | ||
image: alpine/git:v2.26.2 | ||
securityContext: | ||
runAsUser: 0 | ||
script: | | ||
#!/usr/bin/env ash | ||
# Generate a private host key and give the Steps access to its public | ||
# key for their known_hosts file. | ||
ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key | ||
chmod 0600 /etc/ssh/ssh_host_rsa_key* | ||
HOST_PUBLIC_KEY=$(cat /etc/ssh/ssh_host_rsa_key.pub | awk '{ print $2 }') | ||
echo "localhost ssh-rsa $HOST_PUBLIC_KEY" > /messages/known_hosts | ||
# Wait for a Step to supply the server a public key generated from creds-init | ||
# credentials. | ||
while [ ! -f /messages/authorized_keys ] ; do | ||
sleep 1 | ||
done | ||
# Allow Steps to SSH login as root to this server. | ||
mkdir /root/.ssh | ||
cp /messages/authorized_keys /root/.ssh/ | ||
# "Unlock" the root account, allowing SSH login to succeed. | ||
sed -i s/root:!/"root:*"/g /etc/shadow | ||
# Create the git repo we're going to test against. | ||
cd /root/ | ||
mkdir repo | ||
cd repo | ||
git init . --bare | ||
# Start the sshd server. | ||
/usr/sbin/sshd -E /var/log/sshd | ||
touch /messages/sshd-ready | ||
tail -f /var/log/sshd | ||
steps: | ||
- name: setup | ||
# This Step is only necessary as part of the test, it's not something you'll | ||
# ever need in a real-world scenario involving an external git repo. | ||
image: alpine/git:v2.26.2 | ||
securityContext: | ||
runAsUser: 0 | ||
script: | | ||
#!/usr/bin/env ash | ||
# Generate authorized_keys file from the creds-init private key and give | ||
# it to the sidecar server so that Steps can successfully SSH login | ||
# using creds-init credentials. | ||
ssh-keygen -y -f $(credentials.path)/.ssh/id_ssh-key-for-git > /messages/authorized_keys | ||
# Wait for sshd to start on the git server. | ||
while [ ! -f /messages/sshd-ready ] ; do | ||
sleep 1 | ||
done | ||
- name: git-clone-and-push | ||
image: alpine/git:v2.26.2 | ||
securityContext: | ||
runAsUser: 0 | ||
workingDir: /root | ||
script: | | ||
#!/usr/bin/env ash | ||
set -xe | ||
if [ -d /tekton/home/.ssh ] ; then | ||
# When disable-home-env-overwrite is "false", creds-init credentials | ||
# will be copied to /tekton/home/.ssh by the entrypoint. But we need | ||
# them in /root/.ssh. | ||
# Overwrite the creds-init known_hosts file with that of our test | ||
# git server. You wouldn't need to do this in any kind of real-world | ||
# scenario involving an external git repo. | ||
cp /messages/known_hosts $(credentials.path)/.ssh/ | ||
# Symlink /tekton/creds/.ssh to /root/.ssh because this script issues | ||
# vanilla git commands of its own. Git PipelineResources and the git-clone | ||
# catalog task handle this for you. | ||
ln -s $(credentials.path)/.ssh /root/.ssh | ||
else | ||
# When disable-home-env-overwrite is "true", creds-init credentials | ||
# will be copied to /root/.ssh by the entrypoint. We just need to | ||
# overwrite the known_hosts file with that of our test git server. | ||
cp /messages/known_hosts /root/.ssh/known_hosts | ||
fi | ||
git clone root@localhost:/root/repo ./repo | ||
cd repo | ||
git config user.email "[email protected]" | ||
git config user.name "Example" | ||
echo "Hello, world!" > README | ||
git add README | ||
git commit -m "Test commit!" | ||
git push origin master | ||
- name: git-clone-and-check | ||
image: gcr.io/tekton-releases/dogfooding/alpine-git-nonroot:latest | ||
# Because this Step runs with a non-root security context, the creds-init | ||
# credentials will fail to copy into /tekton/home. This happens because | ||
# our previous step _already_ wrote to /tekton/home and ran as a root | ||
# user. So there will be warning messages reporting "unsuccessful cred | ||
# copy". These can be safely ignored and instead this Step will copy | ||
# the credentials out of /tekton/creds to nonroot's HOME directory. | ||
securityContext: | ||
runAsUser: 1000 | ||
workingDir: /home/nonroot | ||
script: | | ||
#!/usr/bin/env ash | ||
set -xe | ||
if [ -d /tekton/home/.ssh ] ; then | ||
# When disable-home-env-overwrite is "false", creds-init credentials | ||
# will be copied to /tekton/home/.ssh by the entrypoint. But we need | ||
# them in /home/nonroot/.ssh. | ||
# Overwrite the creds-init known_hosts file with that of our test | ||
# git server. You wouldn't need to do this in any kind of real-world | ||
# scenario involving an external git repo. | ||
cp /messages/known_hosts $(credentials.path)/.ssh/ | ||
# Symlink /tekton/creds/.ssh to /home/nonroot/.ssh because this script issues | ||
# vanilla git commands of its own and we're running as a non-root user. | ||
# Git PipelineResources and the git-clone catalog task handle this for you. | ||
ln -s $(credentials.path)/.ssh /home/nonroot/.ssh | ||
else | ||
# When disable-home-env-overwrite is "true", creds-init credentials | ||
# will be copied to /home/nonroot/.ssh by the entrypoint. We just need to | ||
# overwrite the known_hosts file with that of our test git server. | ||
cp /messages/known_hosts /home/nonroot/ssh/known_hosts | ||
fi | ||
git clone root@localhost:/root/repo ./repo | ||
cd repo | ||
cat README | grep "Hello, world!" |
Oops, something went wrong.