Socket in your Gitlab Pipeline
Socket fights vulnerabilities and provides visibility, defense-in-depth, and proactive supply chain protection for your open source dependencies. It is easy to integrate Socket into your Gitlab Pipeline to provide an extra layer of security against Supply Chain Attacks.
Adding Socket to your pipeline
Create your Socket API Key
You can either create your API Key yourself if you have permissions in your socket.dev account or you can have your Admin create it for you with the Reports scope.
-
Log into the socket.dev dashboard
-
Go to Settings
-
Go to the API Tokens tab
-
Select Create API Token
-
Give the token a name like Gitlab API Token
-
Select the report Scope
-
Click Confirm
-
Click on Show key
-
Click on the API Token to copy
Get your Socket Org ID
-
In the
username
portion of the tester put in your Socker API Key -
Click try it
-
Save the ID from the response
Create your Socket Environment variables
-
Log into Gitlab
-
Navigate to your project
-
Go to Settings -> CI/CD
-
Expand Variables
-
Do Add Variable
-
Select Mask Variable
-
Key: SOCKET_SECURITY_API_KEY
-
Value: Socket API Token
-
-
Click Add variable
-
Add another variable
- Key:
SOCKET_ORG_ID
- Value: org_id
- Key:
-
If you would like comments about security findings on an unhealthy report you will need a gitlab access token
- Key:
GITLAB_TOKEN
- Value: gitlab_token_with_access
- Key:
Example Gitlab Pipeline Setup
-
Go to Build
-
Go to Pipeline Editor
-
Paste the following Pipeline Yaml, or integrate with your existing code
test: image: node:latest rules: - if: $CI_MERGE_REQUEST_ID when: always changes: - package.json - package-lock.json - when: never before_script: - apt-get -qq update - apt-get install -y jq script: - npm install -g @socketsecurity/cli - | SOCKET_SETTINGS_FILE=socket_settings.json SHOW_ALL=0 # base64 encode API Token SOCKET_TOKEN=$(printf "$SOCKET_SECURITY_API_KEY:" | base64) # Get the Org Settings curl -s --location 'https://api.socket.dev/v0/settings' \ --header 'Content-Type: application/json' \ --header "Authorization: Basic $SOCKET_TOKEN" \ --data '[{"organization": "'$SOCKET_ORG_ID'"}]' > $SOCKET_SETTINGS_FILE # Org settings parse echo "Getting Security Policy" ORG_SETTINGS=$(cat $SOCKET_SETTINGS_FILE | jq -r ' .entries[].settings.organization as $top | $top | .issueRules | keys | .[] as $issue | $top | .issueRules[$issue].action as $action | $issue + "=" + $action' | sort) DEFAULT_SETTINGS=$(cat $SOCKET_SETTINGS_FILE | jq -r ' .defaults as $top | $top | .issueRules | keys | .[] as $issue | $top | .issueRules[$issue].action as $action | $issue + "=" + $action' | sort) # Clean up settings file rm $SOCKET_SETTINGS_FILE set -- for SETTING in $DEFAULT_SETTINGS; do if [[ $ORG_SETTINGS == *"$SETTING"* ]]; then echo "$SETTING set at org level" > /dev/null else set -- "$@" $SETTING fi done for SETTING in $ORG_SETTINGS; do set -- "$@" $SETTING done # Report Parse # Commented out one is to test with saved output # REPORT_RESULT=$(cat output.json | jq -r '("scan_passed=" + (if .healthy then "true" else "false" end) ),(.issues[] | .type as $type | .value | .severity as $severity | .category as $category | .locations[] | .type as $ecosystem | .value | (.package + "@" + .version) as $package | $severity + "," + $category + "," + $type + "," + $ecosystem + "," + $package)') echo "Running Scan" REPORT_RESULT=$(socket ci --all --json . 2>&1 | tail +5 | jq -r '("scan_passed=" + (if .healthy then "true" else "false" end) ),(.issues[] | .type as $type | .value | .severity as $severity | .category as $category | .locations[] | .type as $ecosystem | .value | (.package + "@" + .version) as $package | $severity + "," + $category + "," + $type + "," + $ecosystem + "," + $package)') SCAN_PASSED=0 for RESULT in $REPORT_RESULT; do if [[ $RESULT == *"scan_passed"* ]]; then echo $RESULT > /dev/null SCAN_RESULT=$(echo $RESULT | awk 'BEGIN{FS="="}{print $2}') if [ $SCAN_RESULT == 'false' ]; then $SCAN_PASSED=1 fi else TYPE=$(echo $RESULT | awk 'BEGIN{FS=","}{print $3}') for SETTING in $@; do NAME=$(echo $SETTING | awk 'BEGIN{FS="="}{print $1}') ACTION=$(echo $SETTING | awk 'BEGIN{FS="="}{print $2}') SHOWN=1 # echo "$NAME=$TYPE" # echo $ACTION if [ $NAME == $TYPE ] && [ $ACTION == 'error' ]; then RESULT=$(echo $RESULT | sed s/didYouMean/typosquat/g) if [ -z $OUTPUT ]; then OUTPUT=$RESULT else OUTPUT="$OUTPUT;$RESULT" fi if [ $SCAN_PASSED -eq 0 ]; then SCAN_PASSED=1 # echo "SCAN FAILED" fi fi if [ $SHOW_ALL -eq 1 ] && [ $SHOWN -eq 1 ]; then if [ -z $OUTPUT ]; then OUTPUT=$RESULT else OUTPUT="$OUTPUT;$RESULT" fi fi done fi done if [ $SCAN_PASSED -eq 0 ]; then echo "scan_passed=true" else echo "scan_passed=false" echo "Adding comment to merge request" comment_for_merge="# Socket Security: Security issues detected.\n\nLearn more about [socket.dev](https://socket.dev/?utm_medium=gh)\n\nThe following issues were detected\n\n| Severity | Category | Type | Ecosystem | Package |\\n| -------- | -------- | ---- | --------- | ------- |\\n|$(echo $OUTPUT | sed 's/;/|\\n|/g' | sed 's/,/|/g')|" curl -s --location --request POST "https://gitlab.com/api/v4/projects/$CI_MERGE_REQUEST_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes" --header "PRIVATE-TOKEN: $GITLAB_TOKEN" --header "Content-Type: application/json" --data-raw "{ \"body\": \"$comment_for_merge\" }" fi echo $OUTPUT | sed 's/;/\n/g' exit $SCAN_PASSED
-
Commit changes to your main branch or the current branch you are working on
Testing pipeline
-
Create a new branch
-
Modify or add a
package.json
-
Create a new Merge request
-
Confirm that the Socket CI pipeline job ran
-
Confirm that for an unhealthy report a comment is left on the Merge request
Updated 3 months ago
That's it! You're all done now any time there is an update to your manifest file the Socket CI will automatically run. You can update the criteria to add more things like requirements.txt
or other lock files.