Что такое Secrets not found?

Ошибка Secrets not found возникает, когда CI/CD пайплайн не может найти необходимые секреты (пароли, токены, ключи) для выполнения операций, что приводит к сбою процесса.

Причины возникновения

  • Секреты не настроены в CI/CD системе
  • Неправильные имена переменных окружения
  • Проблемы с правами доступа к секретам
  • Секреты устарели или были удалены
  • Проблемы с шифрованием секретов
  • Неправильная конфигурация vault или secret manager
  • Проблемы с сетью при доступе к секретам
  • Ошибки в скриптах загрузки секретов

Как отладить ошибку

  1. Проверь наличие секретов - убедись в их существовании в системе
  2. Проверь имена переменных - убедись в правильности названий
  3. Проверь права доступа - убедись в наличии необходимых прав
  4. Проверь конфигурацию - убедись в правильности настроек
  5. Проверь сетевые подключения - убедись в доступности secret manager

Как исправить ошибку

1. Настрой секреты в GitHub Actions

 1# .github/workflows/secrets.yml
 2name: Secrets Management
 3on: [push]
 4
 5jobs:
 6  deploy:
 7    runs-on: ubuntu-latest
 8    steps:
 9    - uses: actions/checkout@v3
10    
11    - name: Check secrets availability
12      run: |
13        # Проверка наличия секретов
14        if [ -z "${{ secrets.DATABASE_URL }}" ]; then
15          echo "DATABASE_URL secret is missing"
16          exit 1
17        fi
18        
19        if [ -z "${{ secrets.API_KEY }}" ]; then
20          echo "API_KEY secret is missing"
21          exit 1
22        fi
23    
24    - name: Deploy with secrets
25      run: |
26        # Использование секретов
27        echo "Deploying with database: ${{ secrets.DATABASE_URL }}"
28        echo "Using API key: ${{ secrets.API_KEY }}"
29        
30        # Логика деплоя
31        kubectl set env deployment/my-app \
32          DATABASE_URL="${{ secrets.DATABASE_URL }}" \
33          API_KEY="${{ secrets.API_KEY }}"

2. Настрой секреты в GitLab CI

 1# .gitlab-ci.yml
 2variables:
 3  DOCKER_DRIVER: overlay2
 4
 5stages:
 6  - deploy
 7
 8deploy:
 9  stage: deploy
10  image: alpine:latest
11  before_script:
12    - apk add --no-cache curl
13  script:
14    - |
15      # Проверка секретов
16      if [ -z "$DATABASE_URL" ]; then
17        echo "DATABASE_URL variable is not set"
18        exit 1
19      fi
20      
21      if [ -z "$API_KEY" ]; then
22        echo "API_KEY variable is not set"
23        exit 1
24      fi
25      
26      # Деплой с секретами
27      curl -X POST "https://api.example.com/deploy" \
28        -H "Authorization: Bearer $API_KEY" \
29        -H "Content-Type: application/json" \
30        -d "{\"database_url\":\"$DATABASE_URL\"}"
31  only:
32    - main

3. Настрой секреты в Jenkins

 1// Jenkinsfile
 2pipeline {
 3    agent any
 4    
 5    environment {
 6        DATABASE_URL = credentials('database-url')
 7        API_KEY = credentials('api-key')
 8    }
 9    
10    stages {
11        stage('Check Secrets') {
12            steps {
13                script {
14                    // Проверка наличия секретов
15                    if (env.DATABASE_URL == null || env.DATABASE_URL.isEmpty()) {
16                        error "DATABASE_URL secret is missing"
17                    }
18                    
19                    if (env.API_KEY == null || env.API_KEY.isEmpty()) {
20                        error "API_KEY secret is missing"
21                    }
22                    
23                    echo "All secrets are available"
24                }
25            }
26        }
27        
28        stage('Deploy') {
29            steps {
30                script {
31                    // Использование секретов
32                    sh """
33                        echo "Deploying with database: \$DATABASE_URL"
34                        echo "Using API key: \$API_KEY"
35                        
36                        # Логика деплоя
37                        kubectl set env deployment/my-app \\
38                          DATABASE_URL="\$DATABASE_URL" \\
39                          API_KEY="\$API_KEY"
40                    """
41                }
42            }
43        }
44    }
45}

4. Настрой секреты в Kubernetes

 1# k8s-secret.yaml
 2apiVersion: v1
 3kind: Secret
 4metadata:
 5  name: app-secrets
 6  namespace: default
 7type: Opaque
 8data:
 9  database-url: <base64-encoded-database-url>
10  api-key: <base64-encoded-api-key>
11  jwt-secret: <base64-encoded-jwt-secret>
12
13---
14apiVersion: apps/v1
15kind: Deployment
16metadata:
17  name: my-app
18spec:
19  replicas: 3
20  selector:
21    matchLabels:
22      app: my-app
23  template:
24    metadata:
25      labels:
26        app: my-app
27    spec:
28      containers:
29      - name: my-app
30        image: my-app:latest
31        env:
32        - name: DATABASE_URL
33          valueFrom:
34            secretKeyRef:
35              name: app-secrets
36              key: database-url
37        - name: API_KEY
38          valueFrom:
39            secretKeyRef:
40              name: app-secrets
41              key: api-key
42        - name: JWT_SECRET
43          valueFrom:
44            secretKeyRef:
45              name: app-secrets
46              key: jwt-secret

5. Настрой проверку секретов

 1# secrets_validator.py
 2import os
 3import sys
 4from typing import List, Dict
 5
 6class SecretsValidator:
 7    def __init__(self, required_secrets: List[str]):
 8        self.required_secrets = required_secrets
 9        self.missing_secrets = []
10    
11    def validate_secrets(self) -> bool:
12        """Проверка наличия всех необходимых секретов"""
13        for secret in self.required_secrets:
14            if not os.getenv(secret):
15                self.missing_secrets.append(secret)
16        
17        if self.missing_secrets:
18            print(f"Missing secrets: {', '.join(self.missing_secrets)}")
19            return False
20        
21        print("All required secrets are available")
22        return True
23    
24    def validate_secret_format(self, secret_name: str, expected_format: str) -> bool:
25        """Проверка формата секрета"""
26        secret_value = os.getenv(secret_name)
27        if not secret_value:
28            print(f"Secret {secret_name} is not set")
29            return False
30        
31        # Проверка формата (пример для URL)
32        if expected_format == "url" and not secret_value.startswith(("http://", "https://")):
33            print(f"Secret {secret_name} is not a valid URL")
34            return False
35        
36        return True
37    
38    def get_secrets_info(self) -> Dict[str, str]:
39        """Получение информации о секретах (без значений)"""
40        secrets_info = {}
41        for secret in self.required_secrets:
42            if os.getenv(secret):
43                secrets_info[secret] = "***SET***"
44            else:
45                secrets_info[secret] = "***MISSING***"
46        
47        return secrets_info
48
49# Использование
50if __name__ == "__main__":
51    validator = SecretsValidator([
52        "DATABASE_URL",
53        "API_KEY", 
54        "JWT_SECRET",
55        "REDIS_URL"
56    ])
57    
58    if not validator.validate_secrets():
59        print("Secrets validation failed")
60        sys.exit(1)
61    
62    print("Secrets validation passed")
63    print("Secrets status:", validator.get_secrets_info())

Как мониторить подобные ошибки

  • Настрой алерты на missing secrets
  • Мониторь доступность secret manager
  • Отслеживай использование секретов
  • Настрой мониторинг прав доступа
  • Используй метрики для анализа проблем

FAQ

В: Как безопасно хранить секреты в CI/CD?

О: Используй встроенные secret managers, шифруй секреты, применяй принцип минимальных прав.

В: Что делать, если секреты устарели?

О: Настрой автоматическую ротацию секретов, используй временные токены, применяй secret rotation.

В: Как избежать утечек секретов в логах?

О: Используй маскирование в логах, настрой правильные уровни логирования, применяй secret scanning.

Лучшие практики

  • Всегда проверяй наличие секретов перед использованием
  • Используй встроенные secret managers CI/CD систем
  • Настрой автоматическую ротацию секретов
  • Мониторь доступность и использование секретов
  • Применяй принцип минимальных прав
  • Используй secret scanning для предотвращения утечек