---
title: Unpinned actions full length commit SHA
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Infrastructure as Code (IaC)
  Security > IaC Security Rules > Unpinned actions full length commit SHA
---

# Unpinned actions full length commit SHA

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

## Metadata{% #metadata %}

**Id:** `cicd-github-unpinned-actions-full-length-commit-sha` 

**Provider:** GitHub

**Platform:** CICD

**Severity:** Low

**Category:** Supply-Chain

#### Learn More{% #learn-more %}

- [Provider Reference](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions)

### Description{% #description %}

Steps that reference external GitHub Actions must be pinned to a full-length commit SHA to ensure the action's code is immutable and to reduce supply-chain tampering or unexpected behavior from upstream updates. The rule inspects the `uses` property in `step` attributes and requires the value to end with `@` followed by a 40-character lowercase hexadecimal commit SHA (pattern `@[a-f0-9]{40}`). Entries that do not match this pattern will be flagged. The check ignores local actions referenced with relative paths, starting with `./`, and references beginning with `actions/`. When pinning, use a commit SHA from the action's original repository so the pinned reference matches the intended source.

Secure example with a pinned action:

```yaml
- name: Build and push
  uses: docker/build-push-action@e3b0c44298fc1c149afbf4c8996fb92427ae41e4
```

## Compliant Code Examples{% #compliant-code-examples %}

```yaml
name: test-positive
on:
  pull_request:
    types: [opened, synchronize, edited, reopened]
    branches: 
      - master
jobs:
  test-positive:
    runs-on: ubuntu-latest
    steps:
    - name: PR comment
      uses: thollander/actions-comment-pull-request@b07c7f86be67002023e6cb13f57df3f21cdd3411
      with:
        comment_tag: title_check
        mode: recreate
        create_if_not_exists: true
```

```yaml
name: test-positive
on:
  pull_request:
    types: [opened, synchronize, edited, reopened]
    branches:
      - master
jobs:
  test-positive:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout Code
      uses: actions/checkout@v4
      with:
        persist-credentials: false
```

```yaml
name: test-negative3
on:
  pull_request:
    types: [opened, synchronize, edited, reopened]
    branches:
      - master
jobs:
  test-negative3:
    runs-on: ubuntu-latest
    steps:
    - name: Local action
      uses: ./test.yml
```

## Non-Compliant Code Examples{% #non-compliant-code-examples %}

```yaml
name: test-positive
on:
  pull_request:
    types: [opened, synchronize, edited, reopened]
    branches: 
      - master
jobs:
  test-positive:
    runs-on: ubuntu-latest
    steps:
    - name: PR comment
      uses: thollander/actions-comment-pull-request@v2
      with:
        comment_tag: title_check
        mode: recreate
        create_if_not_exists: true
```

```yaml
name: Composite action with unpinned third-party action
description: Composite action that calls a third-party action by tag instead of SHA
runs:
  using: composite
  steps:
    - name: PR comment
      uses: thollander/actions-comment-pull-request@v2
```

```yaml
name: test-positive
on:
  pull_request:
    types: [opened, synchronize, edited, reopened]
    branches: 
      - master
jobs:
  test-positive:
    uses: my-org/shared-github-actions/.github/workflows/pr-comment-thollander.yml@v3
```
