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

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# Hardcoded credential in service environment

{% 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:** `dockercompose-hardcoded-credential-in-environment` 

**Platform:** DockerCompose

**Severity:** High

**Category:** Secret Management

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

- [Provider Reference](https://docs.docker.com/reference/compose-file/services/#environment)

### Description{% #description %}

Storing credentials such as passwords, API keys, or tokens as literal values in the `environment` section exposes them in version control, container inspect output, and process listings. Any developer, CI system, or attacker with read access to the Compose file or the running container can retrieve the credential. Sensitive values should be passed via Docker secrets (`secrets:`) or referenced as environment variable placeholders (e.g., `DB_PASSWORD: ${DB_PASSWORD}`) rather than hardcoded literals.

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

```yaml
services:
  env_refs:
    image: alpine
    environment:
      DB_PASSWORD: ${DB_PASSWORD}
      API_KEY: $API_KEY
      AUTH_TOKEN: ${AUTH_TOKEN:?missing token}
      PRIVATE_KEY: ${PRIVATE_KEY?missing key}
      DB_PASSWORD_NESTED: ${DB_PASSWORD:-${FALLBACK_PASSWORD}}
      DB_PASSWORD_REF: ${DB_PASSWORD:-$FALLBACK_PASSWORD}
      DB_PASSWORD_UNSET: ${PRIMARY_PASSWORD-$FALLBACK_PASSWORD}
      DB_PASSWORD_NESTED_ERR: ${PRIMARY_PASSWORD:-${FALLBACK_PASSWORD:?missing}}
      DB_PASSWORD_NESTED_DEEP: ${PRIMARY_PASSWORD:-${SECONDARY_PASSWORD:-$LEGACY_PASSWORD}}
      DB_PASSWORD_EMPTY: ${DB_PASSWORD:-}
      DB_PASSWORD_ALT: ${DB_PASSWORD:+$FALLBACK_PASSWORD}
      DB_PASSWORD_ALT_UNSET: ${PRIMARY_PASSWORD+$FALLBACK_PASSWORD}
      DB_PASSWORD_ALT_NESTED: ${PRIMARY_PASSWORD:+${FALLBACK_PASSWORD}}
  no_creds:
    image: alpine
    environment:
      PORT: "8080"
      APP_NAME: myapp
      SECRET_NAME: database_password
      TOKEN_URL: https://auth.example.com/token
      GOOGLE_APPLICATION_CREDENTIALS: /run/secrets/gcp.json
      DB_PASSWORD_FILE: /run/secrets/db_password
```

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

```yaml
services:
  object_env:
    image: alpine
    environment:
      DB_PASSWORD: secret123
  list_env:
    image: alpine
    environment:
      - MYSQL_ROOT_PASSWORD=hunter2
  client_secret:
    image: alpine
    environment:
      CLIENT_SECRET: client-secret
  aws_secret_access_key:
    image: alpine
    environment:
      AWS_SECRET_ACCESS_KEY: access-key
  django_secret_key:
    image: alpine
    environment:
      SECRET_KEY: django-secret
  aws_access_key_id:
    image: alpine
    environment:
      AWS_ACCESS_KEY_ID: AKIAEXAMPLE
  compact_api_key:
    image: alpine
    environment:
      APIKEY: api-key
  rails_secret_key_base:
    image: alpine
    environment:
      SECRET_KEY_BASE: rails-secret
  fallback_literal:
    image: alpine
    environment:
      DB_PASSWORD: ${DB_PASSWORD:-supersecret}
  alt_literal:
    image: alpine
    environment:
      DB_PASSWORD: ${DB_PASSWORD:+supersecret}
```
