GITHUB

Compatible avec :

Ce document explique comment ingérer des journaux d'audit GitHub dans Google Security Operations à l'aide d'Amazon S3. L'analyseur tente d'extraire les données du champ "message" à l'aide de différents modèles Grok, en gérant les formats JSON et non JSON. En fonction du "process_type" extrait, il applique une logique d'analyse spécifique à l'aide de filtres grok, kv et autres pour mapper les données de journal brutes dans le schéma UDM (Unified Data Model).

Avant de commencer

Assurez-vous de remplir les conditions suivantes :

  • Instance Google SecOps.
  • Accès privilégié au locataire GitHub Enterprise Cloud avec les autorisations de propriétaire de l'entreprise.
  • Accès privilégié à AWS (S3, IAM).

Recueillir les conditions préalables de GitHub Enterprise Cloud (accès Enterprise)

  1. Connectez-vous à la console d'administration GitHub Enterprise Cloud.
  2. Accédez à Paramètres Enterprise> Paramètres> Journal d'audit> Streaming du journal.
  3. Assurez-vous de disposer des autorisations de propriétaire de l'entreprise pour configurer le streaming des journaux d'audit.
  4. Copiez et enregistrez les informations suivantes dans un emplacement sécurisé :
    • Nom de GitHub Enterprise
    • Noms des organisations sous l'entreprise

Configurer le bucket AWS S3 et Identity and Access Management pour Google SecOps

  1. Créez un bucket Amazon S3 en suivant ce guide de l'utilisateur : Créer un bucket.
  2. Enregistrez le nom et la région du bucket pour référence ultérieure (par exemple, github-audit-logs).
  3. Créez un utilisateur en suivant ce guide de l'utilisateur : Créer un utilisateur IAM.
  4. Sélectionnez l'utilisateur créé.
  5. Sélectionnez l'onglet Informations d'identification de sécurité.
  6. Cliquez sur Créer une clé d'accès dans la section Clés d'accès.
  7. Sélectionnez Service tiers comme Cas d'utilisation.
  8. Cliquez sur Suivant.
  9. Facultatif : Ajoutez un tag de description.
  10. Cliquez sur Créer une clé d'accès.
  11. Cliquez sur Télécharger le fichier CSV pour enregistrer la clé d'accès et la clé d'accès secrète pour référence ultérieure.
  12. Cliquez sur OK.

Configurer la stratégie IAM pour le streaming GitHub S3

  1. Dans la console AWS, accédez à IAM> Stratégies> Créer une stratégie> onglet JSON.
  2. Copiez et collez le règlement suivant.
  3. JSON de la règle (remplacez github-audit-logs si vous avez saisi un autre nom de bucket) :

    {
    "Version": "2012-10-17",
    "Statement": [
        {
        "Sid": "AllowPutObjects",
        "Effect": "Allow",
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::github-audit-logs/*"
        }
    ]
    }
    
  4. Cliquez sur Suivant > Créer une règle.

  5. Nommez la règle GitHubAuditStreamingPolicy, puis cliquez sur Créer une règle.

  6. Revenez à l'utilisateur IAM créé précédemment.

  7. Sélectionnez l'onglet Autorisations.

  8. Cliquez sur Ajouter des autorisations> Joindre directement des règles.

  9. Recherchez et sélectionnez GitHubAuditStreamingPolicy.

  10. Cliquez sur Suivant > Ajouter des autorisations.

Configurer le streaming des journaux d'audit GitHub Enterprise Cloud

  1. Connectez-vous à GitHub Enterprise Cloud en tant que propriétaire de l'entreprise.
  2. Cliquez sur votre photo de profil, puis sur Paramètres d'entreprise.
  3. Dans la barre latérale du compte d'entreprise, cliquez sur Paramètres> Journal d'audit> Diffusion de journaux.
  4. Sélectionnez Configurer le flux, puis cliquez sur Amazon S3.
  5. Sous Authentification, cliquez sur Clés d'accès.
  6. Fournissez les informations de configuration suivantes :
    • Région : sélectionnez la région du bucket (par exemple, us-east-1).
    • Bucket : saisissez le nom du bucket dans lequel vous souhaitez diffuser le flux (par exemple, github-audit-logs).
    • ID de clé d'accès : saisissez l'ID de clé d'accès de l'utilisateur IAM.
    • Clé secrète : saisissez la clé secrète de l'utilisateur IAM.
  7. Cliquez sur Vérifier le point de terminaison pour vérifier que GitHub peut se connecter au point de terminaison Amazon S3 et y écrire des données.
  8. Une fois le point de terminaison validé, cliquez sur Enregistrer.

Créer un utilisateur et des clés IAM en lecture seule pour Google SecOps

  1. Accédez à la console AWS> IAM> Utilisateurs> Ajouter des utilisateurs.
  2. Cliquez sur Add users (Ajouter des utilisateurs).
  3. Fournissez les informations de configuration suivantes :
    • Utilisateur : saisissez secops-reader.
    • Type d'accès : sélectionnez Clé d'accès – Accès programmatique.
  4. Cliquez sur Créer un utilisateur.
  5. Associez la stratégie de lecture minimale (personnalisée) : Utilisateurs > lecteur-secops > Autorisations > Ajouter des autorisations > Associer des stratégies directement > Créer une stratégie.
  6. JSON :

    {
    "Version": "2012-10-17",
    "Statement": [
        {
        "Effect": "Allow",
        "Action": ["s3:GetObject"],
        "Resource": "arn:aws:s3:::github-audit-logs/*"
        },
        {
        "Effect": "Allow",
        "Action": ["s3:ListBucket"],
        "Resource": "arn:aws:s3:::github-audit-logs"
        }
    ]
    }
    
  7. Nom = secops-reader-policy.

  8. Cliquez sur Créer une règle> recherchez/sélectionnez > Suivant> Ajouter des autorisations.

  9. Créez une clé d'accès pour secops-reader : Identifiants de sécurité> Clés d'accès> Créer une clé d'accès> téléchargez le fichier .CSV (vous collerez ces valeurs dans le flux).

Configurer un flux dans Google SecOps pour ingérer les journaux GitHub

  1. Accédez à Paramètres SIEM> Flux.
  2. Cliquez sur + Ajouter un flux.
  3. Dans le champ Nom du flux, saisissez un nom pour le flux (par exemple, GitHub audit logs).
  4. Sélectionnez Amazon S3 V2 comme type de source.
  5. Sélectionnez GitHub comme type de journal.
  6. Cliquez sur Suivant.
  7. Spécifiez les valeurs des paramètres d'entrée suivants :
    • URI S3 : s3://github-audit-logs/
    • Options de suppression de la source : sélectionnez l'option de suppression de votre choix.
    • Âge maximal des fichiers : incluez les fichiers modifiés au cours des derniers jours. La valeur par défaut est de 180 jours.
    • ID de clé d'accès : clé d'accès utilisateur ayant accès au bucket S3.
    • Clé d'accès secrète : clé secrète de l'utilisateur ayant accès au bucket S3.
    • Espace de noms de l'élément : espace de noms de l'élément.
    • Libellés d'ingestion : libellé appliqué aux événements de ce flux.
  8. Cliquez sur Suivant.
  9. Vérifiez la configuration de votre nouveau flux sur l'écran Finaliser, puis cliquez sur Envoyer.

Table de mappage UDM

Champ de journal Mappage UDM Logique
actor principal.user.userid La valeur est extraite du champ actor.
actor_id principal.user.attribute.labels.value La valeur est extraite du champ actor_id.
actor_ip principal.ip La valeur est extraite du champ actor_ip.
actor_location.country_code principal.location.country_or_region La valeur est extraite du champ actor_location.country_code.
application_name target.application La valeur est extraite du champ application_name.
business target.user.company_name La valeur est extraite du champ business.
business_id target.resource.attribute.labels.value La valeur est extraite du champ business_id.
config.url target.url La valeur est extraite du champ config.url.
created_at metadata.event_timestamp La valeur est convertie de millisecondes UNIX en code temporel.
data.cancelled_at extensions.vulns.vulnerabilities.scan_end_time La valeur est convertie du format ISO8601 en code temporel.
data.email target.email La valeur est extraite du champ data.email.
data.event security_result.about.labels.value La valeur est extraite du champ data.event.
data.events security_result.about.labels.value La valeur est extraite du champ data.events.
data.head_branch security_result.about.labels.value La valeur est extraite du champ data.head_branch.
data.head_sha target.file.sha256 La valeur est extraite du champ data.head_sha.
data.hook_id target.resource.attribute.labels.value La valeur est extraite du champ data.hook_id.
data.started_at extensions.vulns.vulnerabilities.scan_start_time La valeur est convertie du format ISO8601 en code temporel.
data.team target.user.group_identifiers La valeur est extraite du champ data.team.
data.trigger_id security_result.about.labels.value La valeur est extraite du champ data.trigger_id.
data.workflow_id security_result.about.labels.value La valeur est extraite du champ data.workflow_id.
data.workflow_run_id security_result.about.labels.value La valeur est extraite du champ data.workflow_run_id.
enterprise.name additional.fields.value.string_value La valeur est extraite du champ enterprise.name.
external_identity_nameid target.user.email_addresses Si la valeur est une adresse e-mail, elle est ajoutée au tableau target.user.email_addresses.
external_identity_nameid target.user.userid La valeur est extraite du champ external_identity_nameid.
external_identity_username target.user.user_display_name La valeur est extraite du champ external_identity_username.
hashed_token network.session_id La valeur est extraite du champ hashed_token.
job_name target.resource.attribute.labels.value La valeur est extraite du champ job_name.
job_workflow_ref target.resource.attribute.labels.value La valeur est extraite du champ job_workflow_ref.
org target.administrative_domain La valeur est extraite du champ org.
org_id additional.fields.value.string_value La valeur est extraite du champ org_id.
programmatic_access_type additional.fields.value.string_value La valeur est extraite du champ programmatic_access_type.
public_repo additional.fields.value.string_value La valeur est extraite du champ public_repo.
public_repo target.location.name Si la valeur est "false", elle est associée à "PRIVATE". Sinon, il est mappé sur "PUBLIC".
query_string additional.fields.value.string_value La valeur est extraite du champ query_string.
rate_limit_remaining additional.fields.value.string_value La valeur est extraite du champ rate_limit_remaining.
repo target.resource.name La valeur est extraite du champ repo.
repo_id additional.fields.value.string_value La valeur est extraite du champ repo_id.
repository_public additional.fields.value.string_value La valeur est extraite du champ repository_public.
request_body additional.fields.value.string_value La valeur est extraite du champ request_body.
request_method network.http.method La valeur est convertie en majuscules.
route additional.fields.value.string_value La valeur est extraite du champ route.
status_code network.http.response_code La valeur est convertie en nombre entier.
timestamp metadata.event_timestamp La valeur est convertie de millisecondes UNIX en code temporel.
token_id additional.fields.value.string_value La valeur est extraite du champ token_id.
token_scopes additional.fields.value.string_value La valeur est extraite du champ token_scopes.
transport_protocol_name network.application_protocol La valeur est convertie en majuscules.
url_path target.url La valeur est extraite du champ url_path.
user target.user.user_display_name La valeur est extraite du champ user.
user_agent network.http.user_agent La valeur est extraite du champ user_agent.
user_agent network.http.parsed_user_agent La valeur est analysée.
user_id target.user.userid La valeur est extraite du champ user_id.
workflow.name security_result.about.labels.value La valeur est extraite du champ workflow.name.
workflow_run.actor.login principal.user.userid La valeur est extraite du champ workflow_run.actor.login.
workflow_run.event additional.fields.value.string_value La valeur est extraite du champ workflow_run.event.
workflow_run.head_branch security_result.about.labels.value La valeur est extraite du champ workflow_run.head_branch.
workflow_run.head_sha target.file.sha256 La valeur est extraite du champ workflow_run.head_sha.
workflow_run.id target.resource.attribute.labels.value La valeur est extraite du champ workflow_run.id.
workflow_run.workflow_id security_result.about.labels.value La valeur est extraite du champ workflow_run.workflow_id.
N/A metadata.event_type La valeur est déterminée en fonction des champs action et actor. Si le champ action contient "_member", la valeur est définie sur "USER_RESOURCE_UPDATE_PERMISSIONS". Si les champs action et actor ne sont pas vides, la valeur est définie sur "USER_RESOURCE_UPDATE_CONTENT". Sinon, la valeur est définie sur "USER_RESOURCE_ACCESS".
N/A metadata.log_type La valeur est définie sur "GITHUB".
N/A metadata.product_name La valeur est définie sur "GITHUB".
N/A metadata.vendor_name La valeur est définie sur "GITHUB".
N/A target.resource.resource_type La valeur est définie sur "STORAGE_OBJECT".
N/A security_result.about.labels.key La valeur est définie sur une chaîne constante en fonction du champ data correspondant. Par exemple, pour data.workflow_id, la clé est définie sur "ID du workflow".
N/A target.resource.attribute.labels.key La valeur est définie sur une chaîne constante en fonction du champ data correspondant. Par exemple, pour data.hook_id, la clé est définie sur "Hook Id".

Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.