Service account — это не пользователь, а идентичность (identity) внутри Google Cloud, которой можно назначать права (IAM-ролии). service account.json обычно — это JSON-файл с приватным ключом для конкретного сервисного аккаунта. Он позволяет приложению аутентифицироваться в Google API и Firebase Admin SDK как этот сервисный аккаунт, чтобы выполнять операции от имени проекта: читать/писать Firestore, работать с Cloud Storage, отправлять FCM и т.д.
Основная цель файла — дать серверному коду возможность безопасно общаться с ресурсами Firebase/GCP. Но хранение приватного ключа в виде файла накладывает ответственность: при попадании файла в чужие руки злоумышленник получает доступ к ресурсам, на которые сервисный аккаунт имеет права.
Типичный service account JSON выглядит так (анонимизировано):
{ "type": "service_account", "project_id": "my-firebase-project-123", "private_key_id": "abcdef1234567890", "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkq...\n-----END PRIVATE KEY-----\n", "client_email": "sa-name@my-firebase-project-123.iam.gserviceaccount.com", "client_id": "12345678901234567890", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/sa-name%40my-firebase-project-123.iam.gserviceaccount.com" }
Ключевые поля:
Важно: сам JSON содержит секрет (private_key). Его нельзя публиковать.
Через Google Cloud Console / Firebase Console: 1. Перейдите в IAM & Admin → Service Accounts. 2. Создайте новый сервисный аккаунт (Name, Description). 3. Назначьте минимальный набор ролей (см. раздел про least privilege). 4. На вкладке Keys → Create key → JSON → Скачать.
Через gcloud:
Создать аккаунт: gcloud iam service-accounts create my-firebase-sa \ --display-name="Service account for Firebase admin tasks"
Назначить роль (пример: доступ только к Cloud Firestore): gcloud projects add-iam-policy-binding my-firebase-project-123 \ --member="serviceAccount:my-firebase-sa@my-firebase-project-123.iam.gserviceaccount.com" \ --role="roles/datastore.user"
Создать ключ: gcloud iam service-accounts keys create ./service-account.json \ --iam-account=my-firebase-sa@my-firebase-project-123.iam.gserviceaccount.com
После выполнения файл service-account.json окажется в рабочей директории. Сразу перенесите его в безопасное хранилище.
Node.js (инициализация с локальным файлом):
const admin = require('firebase-admin'); const serviceAccount = require('/path/to/service-account.json');
admin.initializeApp({ credential: admin.credential.cert(serviceAccount), storageBucket: 'my-firebase-project-123.appspot.com' });
Python:
import firebase_admin from firebase_admin import credentials
cred = credentials.Certificate('/path/to/service-account.json') firebase_admin.initialize_app(cred, {'storageBucket': 'my-firebase-project-123.appspot.com'})
Альтернатива: использовать Application Default Credentials (ADC) — если файл задан через переменную окружения GOOGLE_APPLICATION_CREDENTIALS, SDK автоматически его подхватит.
1. Принцип наименьших привилегий: - Назначайте только нужные роли. Например, для записи в Firestore достаточно roles/datastore.user, для чтения/записи в Cloud Storage — roles/storage.objectAdmin и т.п. - Не используйте роли Owner или Editor без крайней необходимости.
2. Минимизируйте использование ключей: - Внутри GCP используйте встроенные сервисы (Cloud Functions, Cloud Run) и назначайте сервисные аккаунты ресурсам. - Для GKE используйте Workload Identity вместо создания ключей.
3. Короткоживущие креденшалы: - По возможности используйте короткоживущие токены или Workload Identity Federation. - Если используете ключи, планируйте ротацию, например, каждые 90 дней (часто рекомендуемая практика).
4. Хранение секретов: - Храните JSON в Google Secret Manager или в безопасных хранилищах CI (GitHub Secrets, GitLab CI/CD variables), не в репозитории. - В CI извлекайте секрет во временный файл, используйте его и удаляйте немедленно.
5. Мониторинг и аудит: - Включите Audit Logs для IAM и ключевых сервисов (Access Transparency, Admin Activity). - Настройте оповещения на аномальные события: создание новых ключей, привязка ролей, действия с критичными ресурсами.
6. Ограничения на создание ключей: - В крупных организациях можно запретить создание пользовательских ключей для сервисных аккаунтов через организационные политики (Organization Policy) и разрешать только через централизованный процесс.
7. Удаляйте неиспользуемые ключи: - Проверяйте активные ключи в консоли и удаляйте старые/неиспользуемые.
Обнаружение:
Реакция (шаги при подозрении на утечку): 1. Немедленно отозвать ключ: gcloud iam service-accounts keys delete KEY_ID \ --iam-account=my-firebase-sa@my-firebase-project-123.iam.gserviceaccount.com 2. Создать новый ключ и заменить его везде, где использовался старый. 3. Проверить Audit Logs на список действий, совершённых с использованием скомпрометированного аккаунта (IP, временные метки). 4. При необходимости уменьшить права сервисного аккаунта или временно отключить его. 5. Проверить, не была ли компрометирована другая инфраструктура (деплой, CI, хранилище секретов).
Важно: ключи сервисных аккаунтов не имеют автоматической даты истечения, поэтому отозвать их нужно вручную или настроить политику ротации.
service account.json — мощный и удобный инструмент для доступа серверных приложений к Firebase и GCP, но он несёт в себе риск: один файл с приватным ключом может открыть злоумышленнику весь проект, если у аккаунта широкие права. Практики: минимум прав, избегать долгоживущих ключей, использовать встроенные механизмы GCP (Workload Identity, Secret Manager), регулярно ротация и мониторинг — позволяют снизить риск. Если ключ всё же утек — действуйте быстро: отозвать, проанализировать логи, заменить ключ и провести пост-инцидентный разбор причин утечки.
Следуя перечисленным шагам и рекомендациям, вы снижаете вероятность компрометации инфраструктуры и делаете работу с Firebase более безопасной и управляемой.