Skip to content

Commit 8d3eb57

Browse files
authored
add artifactory action (#249)
Add the GitHub action to enable rotation for Artifactory pull tokens
1 parent 4d8a59b commit 8d3eb57

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

artifactory-automation/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Automate Artifactory Pull Tokens
2+
3+
Workflow that will automate the creation and updating of pull tokens to allow customers to authenticate with their artifactory instance
4+
5+
For this workflow to run properly, you will need to create an [assumable identity](https://edu.chainguard.dev/chainguard/administration/custom-idps/custom-idps/) beforehand. It will need a role with the correctly scoped permissions.
6+
7+
## Creating the Role and Identity
8+
Create a role that matches the registry.pull_token_creator role.
9+
> [!IMPORTANT]
10+
> If you want to enable pruning of expired pull tokens, you must add identity.list and identity.delete capabilities.
11+
12+
`chainctl iam roles create artifactory --parent <your-organization> --capabilities apk.list,groups.list,identity.create,manifest.list,manifest.metadata.list,record_signatures.list,repo.list,role_bindings.create,roles.list,sboms.list,tag.list,vuln_reports.list,identity.list,identity.delete`
13+
14+
15+
Create the assumable identity
16+
`chainctl iam identities create github artifactory --github-repo=<your-repository> --parent=<your-organization> --role artifactory`
17+
18+
19+
## Example Workflow
20+
21+
```
22+
name: Create Pull Token
23+
24+
on:
25+
workflow_dispatch:
26+
schedule:
27+
- cron: "0 0 * * 0"
28+
29+
permissions:
30+
contents: read
31+
32+
jobs:
33+
authentication:
34+
name: Auth
35+
runs-on: ubuntu-latest
36+
37+
permissions:
38+
contents: read
39+
id-token: write
40+
41+
steps:
42+
- name: "Setup Artifactory Token"
43+
uses: chainguard-dev/artifactory-automation
44+
with:
45+
identity: "some-chainguard/assumable-identity"
46+
organization: test.com
47+
artifactory_url: https://your-artifactory.com
48+
artifactory_user: test_user@test.com
49+
artifactory_repository_name: test_repository
50+
artifactory_token: ${{ secrets.ARTIFACTORY_TOKEN }}
51+
prune_expired: true
52+
```

artifactory-automation/action.yaml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: Artifactory Automation
2+
description: Automates the updating of Chainguard pull tokens and authentication for an Artifactory repository.
3+
4+
inputs:
5+
# String inputs
6+
identity:
7+
description: 'Github assumable identity to Chainguard'
8+
required: true
9+
10+
organization:
11+
description: 'Chainguard Organization Name'
12+
required: true
13+
14+
artifactory_url:
15+
description: 'The url to your artifactory instance'
16+
required: true
17+
18+
artifactory_user:
19+
description: 'The username for artifactory'
20+
required: true
21+
22+
artifactory_repository_name:
23+
description: 'The name of the artifactory repository to update'
24+
required: true
25+
26+
artifactory_token:
27+
description: 'API token for deployment'
28+
required: true
29+
30+
ttl:
31+
description: 'TTL for the token ex: 1h (default is 7 days)'
32+
required: false
33+
default: 168h
34+
35+
prune_expired:
36+
description: 'Prune expired tokens (requires identity.list, identity.delete permissions)'
37+
required: false
38+
default: "false"
39+
40+
runs:
41+
using: "composite"
42+
steps:
43+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
44+
45+
- name: "Auth"
46+
uses: chainguard-dev/setup-chainctl@272698817627c158bbd813cb783b62a4b9bbbc67
47+
with:
48+
identity: ${{ inputs.identity }}
49+
50+
- name: Create Token
51+
shell: bash
52+
id: create_token
53+
env:
54+
ORGANIZATION: ${{ inputs.organization }}
55+
TTL: ${{ inputs.ttl }}
56+
PRUNE: ${{ inputs.prune_expired }}
57+
run: |
58+
if [[ $PRUNE = "true" ]]; then
59+
for id in $(chainctl iam identities list --parent "$ORGANIZATION" --name "pull token - registry" --expired -o json | jq -r '.items[]?.id'); do
60+
echo "Deleting old pull token $id"
61+
chainctl iam identities delete $id --parent "$ORGANIZATION" -y
62+
done
63+
fi
64+
65+
PULL_TOKEN_JSON=$(chainctl auth pull-token --ttl "$TTL" --output json)
66+
67+
user=$(jq -r '.identity_id' <<<$PULL_TOKEN_JSON)
68+
password=$(jq -r '.token' <<<$PULL_TOKEN_JSON)
69+
70+
echo "user=$user" >> $GITHUB_OUTPUT
71+
echo "password=$password" >> $GITHUB_OUTPUT
72+
73+
- name: Update Artifactory Registry
74+
shell: bash
75+
id: update-artifactory
76+
env:
77+
TOKEN_USER: ${{ steps.create_token.outputs.user }}
78+
TOKEN_PASSWORD: ${{ steps.create_token.outputs.password }}
79+
ARTIFACTORY_USER: ${{ inputs.artifactory_user }}
80+
ARTIFACTORY_TOKEN: ${{ inputs.artifactory_token }}
81+
ARTIFACTORY_URL: ${{ inputs.artifactory_url }}
82+
ARTIFACTORY_REPOSITORY_NAME: ${{ inputs.artifactory_repository_name }}
83+
run: |
84+
RESP=$(curl -u "$ARTIFACTORY_USER:$ARTIFACTORY_TOKEN" \
85+
--silent --write-out "HTTPSTATUS:%{http_code}" \
86+
-X POST \
87+
"$ARTIFACTORY_URL/artifactory/api/repositories/$ARTIFACTORY_REPOSITORY_NAME" \
88+
-H "Content-Type: application/json" \
89+
-d '{
90+
"key": "'$ARTIFACTORY_REPOSITORY_NAME'",
91+
"username": "'$TOKEN_USER'",
92+
"password": "'$TOKEN_PASSWORD'"
93+
}')
94+
95+
BODY=$(echo $RESP | sed -e 's/HTTPSTATUS\:.*//g')
96+
STATUS=$(echo $RESP | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
97+
98+
if [ "$STATUS" -ne 200 ]; then
99+
echo "Error $STATUS": $BODY
100+
exit 1
101+
fi
102+
103+
echo $BODY

0 commit comments

Comments
 (0)