Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable auth with OpenID Connect #117

Merged
merged 74 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
a84d19f
initial PR
eranturgeman Dec 31, 2023
d78ce78
adding initial changes
eranturgeman Dec 31, 2023
65dee5b
.
eranturgeman Dec 31, 2023
d7cd2b5
.
eranturgeman Dec 31, 2023
c35e942
added missing input
eranturgeman Dec 31, 2023
3967788
.
eranturgeman Dec 31, 2023
0120f3e
.
eranturgeman Dec 31, 2023
71cbe15
.
eranturgeman Dec 31, 2023
d1a7421
.
eranturgeman Dec 31, 2023
1a56b5c
.
eranturgeman Dec 31, 2023
3ec45ea
.
eranturgeman Dec 31, 2023
e9be534
.
eranturgeman Dec 31, 2023
c838692
.
eranturgeman Dec 31, 2023
8cd79c9
.
eranturgeman Dec 31, 2023
d2db589
.
eranturgeman Dec 31, 2023
a151bfc
.
eranturgeman Dec 31, 2023
a85020f
.
eranturgeman Dec 31, 2023
4ec24ec
.
eranturgeman Dec 31, 2023
e48a58a
.
eranturgeman Dec 31, 2023
4b10a11
.
eranturgeman Dec 31, 2023
6d0d95e
.
eranturgeman Dec 31, 2023
900fa67
Updated README. there are some points to complete
eranturgeman Jan 1, 2024
9a17ec2
added an initial test
eranturgeman Jan 1, 2024
019192f
.
eranturgeman Jan 1, 2024
b9de761
.
eranturgeman Jan 1, 2024
b71be20
.
eranturgeman Jan 1, 2024
2df6b58
.
eranturgeman Jan 1, 2024
f0fb798
.
eranturgeman Jan 1, 2024
fe63eb6
.
eranturgeman Jan 1, 2024
23ac450
.
eranturgeman Jan 1, 2024
6bb31f3
.
eranturgeman Jan 1, 2024
09db5c1
.
eranturgeman Jan 1, 2024
dcea81e
.
eranturgeman Jan 1, 2024
31e8d43
.
eranturgeman Jan 1, 2024
398291d
.
eranturgeman Jan 1, 2024
68b0f6b
.
eranturgeman Jan 1, 2024
142d179
.
eranturgeman Jan 1, 2024
8a928d1
.
eranturgeman Jan 1, 2024
990d09d
.
eranturgeman Jan 1, 2024
24de26e
.
eranturgeman Jan 1, 2024
5720756
.
eranturgeman Jan 1, 2024
6708971
.
eranturgeman Jan 2, 2024
80c4341
.
eranturgeman Jan 3, 2024
cf19438
.
eranturgeman Jan 3, 2024
d027f77
.
eranturgeman Jan 3, 2024
e21f433
fixed readme + inserted all credentials into a struct
eranturgeman Jan 3, 2024
c75c61b
.
eranturgeman Jan 3, 2024
31702fb
.
eranturgeman Jan 3, 2024
bc772cb
fixed all calls and tests. CLI should be working now
eranturgeman Jan 3, 2024
00d094e
removed all TODO and redundant code
eranturgeman Jan 3, 2024
bf4587a
checking for identity mapping with an aud field as a list with severa…
eranturgeman Jan 4, 2024
f9cc259
.
eranturgeman Jan 4, 2024
3076528
updated README
eranturgeman Jan 7, 2024
f52de1d
updated README before Authorization section
eranturgeman Jan 7, 2024
c4749ad
fixed README, updated flow. there are some comments left and some com…
eranturgeman Jan 7, 2024
55e7127
added initial integration test
eranturgeman Jan 7, 2024
f64d8dd
deleted all redundant code and fixed comments & docs
eranturgeman Jan 8, 2024
8e18b21
fixed oidc-test.yml
eranturgeman Jan 9, 2024
93f4807
added trigger on workflow_dispatch
eranturgeman Jan 9, 2024
5d1995b
.
eranturgeman Jan 11, 2024
fe5b1bd
attempt to fix test
eranturgeman Jan 11, 2024
f2e4b69
attempt to fix test
eranturgeman Jan 11, 2024
f164a9a
attempt to fix test
eranturgeman Jan 11, 2024
8c1e8eb
attempt to fix test
eranturgeman Jan 11, 2024
179df46
attempt to fix test
eranturgeman Jan 11, 2024
ae74d37
attempt to fix test
eranturgeman Jan 11, 2024
37ed543
attempt to fix test
eranturgeman Jan 11, 2024
7575644
attempt to fix test
eranturgeman Jan 11, 2024
98e3217
.
eranturgeman Jan 11, 2024
87de600
fixed setup-jfrog-cli to address the public action and not the forked…
eranturgeman Jan 11, 2024
3d558d1
.
eranturgeman Jan 11, 2024
7225d6d
.
eranturgeman Jan 11, 2024
c9c4b89
pr fixes
eranturgeman Jan 16, 2024
6190e53
pr fixes
eranturgeman Jan 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/workflows/oidc-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# This action is an integration test for OIDC workflow
name: OpenID Connect Test
on:
push:
branches:
- '**'
tags-ignore:
- '**'
# Triggers the workflow on labeled PRs only.
pull_request_target:
types: [ labeled ]
# Ensures that only the latest commit is running for each PR at a time.
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.ref }}
cancel-in-progress: true

permissions:
id-token: write

jobs:
OIDC-Test:
if: contains(github.event.pull_request.labels.*.name, 'safe to test') || github.event_name == 'push'
name: OIDC-Access integration test (${{ matrix.os }})
strategy:
fail-fast: false
matrix:
os: [ ubuntu, windows, macos ]
runs-on: ${{ matrix.os }}-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4

# Generating a unique name for the Integration Configuration that will be created in the following step
- name: Generate unique OIDC config name
shell: bash
run: echo "OIDC_CONFIG_NAME=oidc-integration-test-config-$(date +%Y%m%d%H%M%S)" >> $GITHUB_ENV

- name: Create OpenID Connect integration
shell: bash
run: |
curl -X POST "${{ secrets.JFROG_PLATFORM_URL }}/access/api/v1/oidc" -H "Content-Type: application/json" -H "Authorization: Bearer ${{ secrets.JFROG_PLATFORM_RT_TOKEN }}" -d '{
"name": "${{ env.OIDC_CONFIG_NAME }}",
"issuer_url": "https://token.actions.githubusercontent.com/",
"provider_type": "GitHub",
"description": "This is a test configuration created for OIDC-Access integration test" }'

- name: Create OIDC integration Identity Mapping
shell: bash
run: |
curl -X POST ${{ secrets.JFROG_PLATFORM_URL }}/access/api/v1/oidc/${{ env.OIDC_CONFIG_NAME }}/identity_mappings \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer ${{ secrets.JFROG_PLATFORM_RT_TOKEN }}' \
-d '{
"name": "oidc-test-identity-mapping",
"priority": "1",
"claims": {
"sub": "repo:jfrog/setup-jfrog-cli:ref:refs/heads/main",
"iss": "https://token.actions.githubusercontent.com"
},
"token_spec": {
"scope": "applied-permissions/admin",
"expires_in": 60
}
}'

- name: Setup JFrog CLI
uses: ./
env:
JF_URL: ${{ secrets.JFROG_PLATFORM_URL }}
with:
oidc-provider-name: ${{ env.OIDC_CONFIG_NAME }}

- name: Test JFrog CLI
run: |
jf rt ping

# Removing the OIDC integration will remove the Identity Mapping as well
- name: Delete OIDC integration
shell: bash
if: always()
run: |
curl -X DELETE ${{ secrets.JFROG_PLATFORM_URL }}/access/api/v1/oidc/${{ env.OIDC_CONFIG_NAME }} -H 'Authorization: Bearer ${{ secrets.JFROG_PLATFORM_RT_TOKEN }}'
57 changes: 55 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

This GitHub Action downloads, installs and configures JFrog CLI, so that it can be used as part of the workflow.

In addition, the Action includes the following features, when using JFrog CLI to work with JFrog Platform.
* The connection details of the JFrog platform used by JFrog CLI can be stored as secrets. Read more about it [here](#Storing-JFrog-Connection-Details-as-Secrets).
Additionally, the Action incorporates the following features when utilizing JFrog CLI to interact with the JFrog Platform:
* Two distinct methods are available for authenticating with the JFrog Platform. Explore more details [here](#authorization)
* There's no need to add the *build name* and *build number* options and arguments to commands which accept them.
All build related operations will be automatically recorded with the *Workflow Name* as build name and *Run Number* as build number.

Expand All @@ -23,6 +23,12 @@ All build related operations will be automatically recorded with the *Workflow N
- uses: jfrog/setup-jfrog-cli@v3
- run: jf --version
```
# Authorization
JFrog CLI operates in conjunction with the JFrog Platform. In order to facilitate this connection, certain connection details of the JFrog Platform must be provided.
There exist two methods to provide these details, and you only need to choose **one** method:
* The connection details of the JFrog platform can be stored as secrets. Read more about it [here](#storing-jfrog-connection-details-as-secrets).
* The connection details of the JFrog platform can be auto-generated using OpenID Connect protocol. Read more about it [here](#connect-using-openid-connect).


## Storing JFrog connection details as secrets
The connection details of the JFrog platform used by JFrog CLI can be stored as secrets.
Expand Down Expand Up @@ -95,6 +101,53 @@ If you have multiple Config Tokens as secrets, you can use all of them in the wo
| Important: When exposing more than one JFrog configuration to the Action, you should always add the ```jf c use``` command to specify the server to use. |
|----------------------------------------------------------------------------------------------------------------------------------------------------------|

## Connect using OpenID Connect
The sensitive connection details, such as the access token used by JFrog CLI on the JFrog platform, can be automatically generated by the action instead of storing it as a secret in GitHub.
This is made possible by leveraging the OpenID-Connect (OIDC) protocol. This protocol can authenticate the workflow issuer and supply a valid access token, requiring only the JF_URL environment variable.
To utilize the OIDC protocol, follow these steps:
### Platform configuration (To be performed once):
1. **[Configure an OIDC Integration](https://jfrog.com/help/r/jfrog-platform-administration-documentation/configure-an-oidc-integration)**: This phase sets an integration between the Action to the JFrog platform.

| NOTE: |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| The value specified as the 'Provider Name' should be used as the oidc-provider-name input in [Workflow configuration step 2](#workflowstep2) below. |
| The 'Audience' field does not represent the 'aud' claim for insertion into the identity-mapping in [Platform configuration step 2](#platformstep2) below. Only the claims included in the Claims Json created during step 2 will be validated. |

<div id="platformstep2"/>

2. **[Configure an identity mapping](https://jfrog.com/help/r/jfrog-platform-administration-documentation/configure-identity-mappings)**: This phase generates a reference token for authenticating against the JFrog platform. It involves defining the necessary details to enable server authentication of the action issuer and granting the issuer an appropriate access token.
You have the flexibility to define any valid list of claims required for request authentication. You can check a list of the possible claims [here](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token).
Example Claims JSON:
```yml
{
"sub": "repo:my-user-name/project1:ref:refs/heads/main",
"aud": "https://github.com/my-user-name",
"ref": "refs/heads/main",
"repository": "my-user-name/project1",
"iss": "https://token.actions.githubusercontent.com"
}
```
### Workflow configuration (To be performed per workflow):
1. **Set required permissions**: In the course of the protocol's execution, it's imperative to acquire a JSON Web Token (JWT) from GitHub's OIDC provider. To request this token, it's essential to configure the specified permission in the workflow file:
```yml
permissions:
id-token: write
```
<div id="workflowstep2"/>

2. **Pass the 'oidc-provider-name' input to the Action (Required)**: The 'oidc-provider-name' parameter designates the OIDC configuration whose one of its identity mapping should align with the generated JWT claims. This input needs to align with the 'Provider Name' value established within the OIDC configuration.
3. **Pass the 'oidc-audience' input to the Action (Optional)**: The 'oidc-audience' input defines the intended recipients of an ID token (JWT), ensuring access is restricted to authorized recipients for the cloud (Artifactory). By default, it contains the URL of the repository owner.
This value, if transmitted, will be used as an argument in core.getIDToken(), which generates the JWT. It enforces a condition, allowing only workflows within the designated repository/organization to access the cloud role. Read more about it [here](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#customizing-the-audience-value).
```yml
- name: Install JFrog CLI
uses: jfrog/setup-jfrog-cli@v3
env:
JF_URL: ${{ secrets.JF_URL }}
with:
oidc-provider-name: <Provider Name value given in step 1>
oidc-audience: <URL to the intended audience>
```

## Setting the build name and build number when publishing build-info to Artifactory
The Action automatically sets the following environment variables:
*JFROG_CLI_BUILD_NAME* and *JFROG_CLI_BUILD_NUMBER* with the workflow name and run number respectively.
Expand Down
7 changes: 7 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ inputs:
download-repository:
description: "Remote repository in Artifactory pointing to 'https://releases.jfrog.io/artifactory/jfrog-cli'. Use this parameter in case you don't have an Internet access."
required: false
oidc-audience:
description: "Recipient for which the JWT is intended. By default it contains the URL to the repository owner."
required: false
oidc-provider-name:
description: "Provider Name's value that was set in OpenId Connect integration."
required: false

runs:
using: "node16"
main: "lib/main.js"
Expand Down
2 changes: 1 addition & 1 deletion lib/cleanup.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function cleanup() {
return __awaiter(this, void 0, void 0, function* () {
try {
core.startGroup('Cleanup JFrog CLI servers configuration');
yield utils_1.Utils.addCliToPath();
yield utils_1.Utils.getAndAddCliToPath({});
yield utils_1.Utils.removeJFrogServers();
}
catch (error) {
Expand Down
5 changes: 3 additions & 2 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ function main() {
try {
core.startGroup('Setup JFrog CLI');
utils_1.Utils.setCliEnv();
yield utils_1.Utils.addCliToPath();
yield utils_1.Utils.configJFrogServers();
let jfrogCredentials = yield utils_1.Utils.getJfrogCredentials();
yield utils_1.Utils.getAndAddCliToPath(jfrogCredentials);
yield utils_1.Utils.configJFrogServers(jfrogCredentials);
}
catch (error) {
core.setFailed(error.message);
Expand Down