---
title: Hardcoded container credentials
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Infrastructure as Code (IaC)
  Security > IaC Security Rules > Hardcoded container credentials
---

# Hardcoded container credentials

{% 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). ().
{% /alert %}

{% /callout %}

## Metadata{% #metadata %}

**Id:** `d0e1f2a3-b4c5-46d7-e8f9-a0b1c2d3e4f5`

**Cloud Provider:** GitHub

**Platform:** CICD

**Severity:** High

**Category:** Insecure Configurations

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

- [Provider Reference](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idcontainercredentials)

### Description{% #description %}

Hardcoded container registry passwords in GitHub Actions workflows expose credentials to anyone with repository read access and embed secrets in version control history. This increases the risk of credential theft and unauthorized access to private images. Container credentials must be supplied via expressions that reference GitHub Secrets, such as `${{ secrets.DOCKER_PASSWORD }}`, rather than literal string values.

This check validates job-level container credentials `jobs[].container.credentials.password` and service container credentials `jobs[].services[].credentials.password` and will flag passwords that are plain literals instead of expression references. Values that parse as a GitHub Actions expression (curly-brace form) are allowed. Any password not written as an expression should be moved to a repository or organization secret and referenced from the workflow.

Secure configuration examples:

```yaml
jobs:
  build:
    container:
      image: my-registry/my-image:latest
      credentials:
        username: my-registry-user
        password: ${{ secrets.DOCKER_PASSWORD }}

    services:
      redis:
        image: redis:6
        credentials:
          username: redis-user
          password: ${{ secrets.REDIS_PASSWORD }}
```

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

```yaml
name: Secure Container Credentials
on: push

jobs:
  test-container:
    runs-on: ubuntu-latest
    container:
      image: private.registry.com/image:latest
      credentials:
        username: ${{ secrets.REGISTRY_USER }}
        password: ${{ secrets.REGISTRY_PASSWORD }}
    steps:
      - run: echo "Running in container"
  test-service:
    runs-on: ubuntu-latest
    services:
      service1:
        credentials:
          username: ${{ secrets.REGISTRY_USER }}
          password: ${{ secrets.REGISTRY_PASSWORD }}
    steps:
      - run: echo "Running a service"
```

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

```yaml
name: Hardcoded Container Credentials
on: push

jobs:
  test-container:
    runs-on: ubuntu-latest
    container:
      image: private.registry.com/image:latest
      credentials:
        username: myuser
        password: mypassword123
    steps:
      - run: echo "Running in container"
  test-service:
    runs-on: ubuntu-latest
    services:
      service1:
        credentials:
          username: myuser
          password: mypassword123
    steps:
      - run: echo "Running a service"
```
