Collecter les journaux PingIDM (anciennement ForgeRock OpenIDM)
Version de l'analyseur : 4.0
Ce document explique comment ingérer des journaux PingIDM (anciennement ForgeRock OpenIDM) dans Google Security Operations à l'aide de Google Cloud Storage V2.
PingIDM est une plate-forme de gestion des identités qui fournit le provisionnement des utilisateurs, la synchronisation, la gestion des mots de passe et la gouvernance des accès. Il consigne les événements de cycle de vie des identités, les tentatives d'authentification, les opérations de rapprochement et les modifications de configuration dans des journaux d'audit accessibles via REST.
Avant de commencer
Assurez-vous de remplir les conditions préalables suivantes :
- Une instance Google SecOps.
- Un projet GCP avec l'API Cloud Storage activée.
- Autorisations permettant de créer et de gérer des buckets GCS et des règles IAM.
- Autorisations pour créer des services Cloud Run, des sujets Pub/Sub et des jobs Cloud Scheduler.
- Accès privilégié à une instance ForgeRock OpenIDM ou PingIDM avec des identifiants d'administrateur.
Créer un bucket Google Cloud Storage
- Accédez à la console Google Cloud.
- Sélectionnez votre projet ou créez-en un.
- Dans le menu de navigation, accédez à Cloud Storage > Buckets.
- Cliquez sur Créer un bucket.
Fournissez les informations de configuration suivantes :
Paramètre Valeur Attribuez un nom au bucket Saisissez un nom unique (par exemple, forgerock-openidm-audit-logs).Type d'emplacement Choisissez en fonction de vos besoins (région, birégion, multirégion). Emplacement Sélectionnez l'emplacement (par exemple, us-central1).Classe de stockage Standard (recommandé pour les journaux auxquels vous accédez fréquemment) Access control (Contrôle des accès) Uniforme (recommandé) Outils de protection Facultatif : Activez la gestion des versions des objets ou la règle de conservation. Cliquez sur Créer.
Collecter les identifiants ForgeRock OpenIDM
Obtenir l'URL de base ForgeRock OpenIDM
- Connectez-vous à votre instance ForgeRock OpenIDM ou PingIDM.
- Notez votre URL de base dans la barre d'adresse du navigateur.
- Format :
https://openidm.example.com - N'incluez pas de barre oblique finale ni de chemin d'accès comme
/admin.
- Format :
Obtenir des identifiants d'administrateur
- Obtenez des identifiants d'administrateur pour votre instance ForgeRock OpenIDM.
- Vous avez alors besoin de :
- Nom d'utilisateur : nom d'utilisateur administrateur (par exemple,
openidm-admin) - Mot de passe : mot de passe administrateur
- Nom d'utilisateur : nom d'utilisateur administrateur (par exemple,
Vérifier les autorisations
- Connectez-vous à ForgeRock OpenIDM.
- Accédez à Configurer > Préférences système > Audit.
- Si vous pouvez voir la configuration et les thèmes d'audit, vous disposez des autorisations requises.
- Si vous ne voyez pas cette option, contactez votre administrateur pour qu'il vous accorde les autorisations de lecture des journaux d'audit.
Tester l'accès à l'API
Testez vos identifiants avant de procéder à l'intégration :
# Replace with your actual credentials OPENIDM_BASE_URL="[https://openidm.example.com](https://openidm.example.com)" OPENIDM_USERNAME="openidm-admin" OPENIDM_PASSWORD="your-admin-password" # Test API access to authentication audit topic curl -v \ -H "X-OpenIDM-Username: ${OPENIDM_USERNAME}" \ -H "X-OpenIDM-Password: ${OPENIDM_PASSWORD}" \ -H "Accept-API-Version: resource=1.0" \ -H "Accept: application/json" \ "${OPENIDM_BASE_URL}/openidm/audit/authentication?_queryFilter=true&_pageSize=1"
Réponse attendue : HTTP 200 avec un fichier JSON contenant les événements d'audit.
Créer un compte de service pour la fonction Cloud Run
La fonction Cloud Run a besoin d'un compte de service disposant des autorisations nécessaires pour écrire dans le bucket GCS et être appelée par Pub/Sub.
Créer un compte de service
- Dans la console GCP, accédez à IAM et administration > Comptes de service.
- Cliquez sur Créer un compte de service.
- Fournissez les informations de configuration suivantes :
- Service account name (Nom du compte de service) :
forgerock-openidm-collector-sa - Description du compte de service :
Service account for Cloud Run function to collect ForgeRock OpenIDM logs
- Service account name (Nom du compte de service) :
- Cliquez sur Créer et continuer.
- Dans la section Autoriser ce compte de service à accéder au projet, ajoutez les rôles suivants :
- Administrateur des objets Storage : pour écrire des journaux dans le bucket GCS et gérer les fichiers d'état.
- Demandeur Cloud Run : pour permettre à Pub/Sub d'appeler la fonction.
- Demandeur Cloud Functions : pour autoriser l'appel de fonctions.
- Cliquez sur Continuer, puis sur OK.
Accorder des autorisations IAM sur le bucket GCS
- Accédez à Cloud Storage > Buckets.
- Cliquez sur le nom de votre bucket (par exemple,
forgerock-openidm-audit-logs). - Accédez à l'onglet Autorisations.
- Cliquez sur Accorder l'accès.
- Fournissez les informations de configuration suivantes :
- Ajouter des comptes principaux : saisissez l'adresse e-mail du compte de service (par exemple,
forgerock-openidm-collector-sa@PROJECT_ID.iam.gserviceaccount.com). - Attribuer des rôles : sélectionnez Administrateur des objets Storage.
- Ajouter des comptes principaux : saisissez l'adresse e-mail du compte de service (par exemple,
- Cliquez sur Enregistrer.
Créer un sujet Pub/Sub
- Dans la console GCP, accédez à Pub/Sub > Sujets.
- Cliquez sur Créer un sujet.
- Fournissez les informations de configuration suivantes :
- ID du thème :
forgerock-openidm-trigger - Conservez les valeurs par défaut des autres paramètres.
- ID du thème :
- Cliquez sur Créer.
Créer une fonction Cloud Run pour collecter les journaux
- Dans la console GCP, accédez à Cloud Run.
- Cliquez sur Créer un service.
- Sélectionnez Fonction (utilisez un éditeur intégré pour créer une fonction).
Dans la section Configurer, fournissez les informations de configuration suivantes :
Paramètre Valeur Nom du service forgerock-openidm-collectorRégion Sélectionnez la région correspondant à votre bucket GCS (par exemple, us-central1).Durée d'exécution Sélectionnez Python 3.12 ou version ultérieure. Dans la section Déclencheur :
- Cliquez sur + Ajouter un déclencheur.
- Sélectionnez Cloud Pub/Sub.
- Dans Sélectionner un sujet Cloud Pub/Sub, sélectionnez
forgerock-openidm-trigger. - Cliquez sur Enregistrer.
Dans la section Authentification :
- Sélectionnez Exiger l'authentification.
- Consultez Identity and Access Management (IAM).
Faites défiler la page vers le bas, puis développez Conteneurs, mise en réseau, sécurité.
Accédez à l'onglet Sécurité :
- Compte de service : sélectionnez
forgerock-openidm-collector-sa.
- Compte de service : sélectionnez
Accédez à l'onglet Conteneurs :
- Cliquez sur Variables et secrets.
- Cliquez sur + Ajouter une variable pour chaque variable d'environnement :
Nom de la variable Exemple de valeur Description GCS_BUCKETforgerock-openidm-audit-logsNom du bucket GCS GCS_PREFIXopenidmPréfixe des fichiers journaux STATE_KEYopenidm/state.jsonChemin d'accès au fichier d'état OPENIDM_BASE_URLhttps://openidm.example.comURL de base OpenIDM OPENIDM_USERNAMEopenidm-adminNom d'utilisateur de l'administrateur OpenIDM OPENIDM_PASSWORDyour-admin-passwordMot de passe administrateur OpenIDM AUDIT_TOPICSaccess,activity,authentication,config,syncThèmes séparés par une virgule PAGE_SIZE100Enregistrements par page MAX_PAGES50Nombre maximal de pages par thème Dans la section Demandes :
- Délai avant expiration de la requête :
600secondes.
- Délai avant expiration de la requête :
Accédez à l'onglet Paramètres :
- Ressources : mémoire 512 Mio, 1 CPU.
Cliquez sur Créer. Une fois le service créé, l'éditeur de code intégré s'ouvre.
Ajouter un code de fonction
- Saisissez main dans le champ Point d'entrée.
Créez deux fichiers dans l'éditeur :
- main.py:
import functions_framework from google.cloud import storage import json import os import urllib3 from datetime import datetime, timezone # Initialize HTTP client with timeouts http = urllib3.PoolManager( timeout=urllib3.Timeout(connect=5.0, read=30.0), retries=False, ) # Initialize Storage client storage_client = storage.Client() # Environment variables GCS_BUCKET = os.environ.get('GCS_BUCKET') GCS_PREFIX = os.environ.get('GCS_PREFIX', 'openidm') STATE_KEY = os.environ.get('STATE_KEY', 'openidm/state.json') OPENIDM_BASE_URL = os.environ.get('OPENIDM_BASE_URL') OPENIDM_USERNAME = os.environ.get('OPENIDM_USERNAME') OPENIDM_PASSWORD = os.environ.get('OPENIDM_PASSWORD') AUDIT_TOPICS = os.environ.get('AUDIT_TOPICS', 'access,activity,authentication,config,sync').split(',') PAGE_SIZE = int(os.environ.get('PAGE_SIZE', '100')) MAX_PAGES = int(os.environ.get('MAX_PAGES', '50')) @functions_framework.cloud_event def main(cloud_event): """ Cloud Run function triggered by Pub/Sub to fetch ForgeRock OpenIDM logs and write to GCS. """ if not all([GCS_BUCKET, OPENIDM_BASE_URL, OPENIDM_USERNAME, OPENIDM_PASSWORD]): print('Error: Missing required environment variables') return try: bucket = storage_client.bucket(GCS_BUCKET) state = load_state(bucket, STATE_KEY) all_events = [] for topic in AUDIT_TOPICS: topic = topic.strip() print(f"Fetching audit logs for topic: {topic}") events = fetch_audit_logs(topic, state.get(topic, {})) all_events.extend(events) if events: latest_timestamp = max(e.get('timestamp', '') for e in events) state[topic] = { 'last_timestamp': latest_timestamp, 'last_run': datetime.now(timezone.utc).isoformat(), 'events_count': len(events) } if all_events: write_to_gcs(bucket, all_events) save_state(bucket, STATE_KEY, state) print(f"Successfully processed {len(all_events)} audit events") else: print("No new audit events to process") except Exception as e: print(f'Error processing logs: {str(e)}') raise def load_state(bucket, key): try: blob = bucket.blob(key) if blob.exists(): return json.loads(blob.download_as_text()) except Exception as e: print(f"Warning: Could not load state: {e}") return {} def save_state(bucket, key, state): try: blob = bucket.blob(key) blob.upload_from_string(json.dumps(state, indent=2), content_type='application/json') except Exception as e: print(f"Warning: Could not save state: {e}") def fetch_audit_logs(topic, topic_state): base_url = OPENIDM_BASE_URL.rstrip('/') all_events = [] last_timestamp = topic_state.get('last_timestamp') query_filter = 'true' if not last_timestamp else f'timestamp gt "{last_timestamp}"' page_offset = 0 page_count = 0 while page_count < MAX_PAGES: try: url = f"{base_url}/openidm/audit/{topic}" params = { '_queryFilter': query_filter, '_pageSize': str(PAGE_SIZE), '_pagedResultsOffset': str(page_offset), '_sortKeys': 'timestamp' } headers = { 'X-OpenIDM-Username': OPENIDM_USERNAME, 'X-OpenIDM-Password': OPENIDM_PASSWORD, 'Accept-API-Version': 'resource=1.0', 'Accept': 'application/json' } response = http.request('GET', url, fields=params, headers=headers) if response.status != 200: print(f"API error for topic {topic}: {response.status}") break data = json.loads(response.data.decode('utf-8')) events = data.get('result', []) if not events: break all_events.extend(events) page_offset += PAGE_SIZE page_count += 1 if len(events) < PAGE_SIZE: break except Exception as e: print(f"Error for topic {topic}: {str(e)}") break return all_events def write_to_gcs(bucket, events): timestamp = datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S') filename = f"{GCS_PREFIX}/openidm_audit_{timestamp}.json" ndjson_content = '\n'.join([json.dumps(event) for event in events]) bucket.blob(filename).upload_from_string(ndjson_content, content_type='application/x-ndjson')- requirements.txt:
functions-framework==3.* google-cloud-storage==2.* urllib3>=2.0.0Cliquez sur Déployer. Le déploiement prend deux à trois minutes.
Créer une tâche Cloud Scheduler
- Dans la console GCP, accédez à Cloud Scheduler.
- Cliquez sur Créer une tâche.
Fournissez les informations de configuration suivantes :
Paramètre Valeur Nom forgerock-openidm-collector-hourlyRégion Sélectionnez la même région que la fonction Cloud Run. Fréquence 0 * * * *(toutes les heures)Fuseau horaire Sélectionnez un fuseau horaire (UTC recommandé). Type de cible Pub/Sub Sujet forgerock-openidm-triggerCorps du message {}Cliquez sur Créer.
Options de fréquence de programmation
| Fréquence | Expression Cron | Cas d'utilisation |
|---|---|---|
| Toutes les 5 minutes | */5 * * * * |
Volume élevé, faible latence |
| Toutes les heures | 0 * * * * |
Standard (recommandé) |
| Tous les jours | 0 0 * * * |
Collecte par lot |
Tester l'intégration
- Dans Cloud Scheduler, cliquez sur Forcer l'exécution pour votre job.
- Vérifiez l'exécution dans les journaux Cloud Run. Recherchez :
Successfully processed X audit events. - Vérifiez qu'un fichier
jsona été créé dans votre bucket Cloud Storage, sous le dossieropenidm/.
Récupérer le compte de service Google SecOps
Configurer un flux dans Google SecOps
- Accédez à Paramètres SIEM > Flux.
- Cliquez sur Ajouter un flux > Configurer un seul flux.
- Nom du flux :
ForgeRock OpenIDM Audit Logs. - Type de source : Google Cloud Storage V2.
- Type de journal : FORGEROCK_OPENIDM.
- Cliquez sur Obtenir un compte de service et copiez l'adresse e-mail fournie (par exemple,
chronicle-12345...). - Cliquez sur Suivant.
- URL du bucket de stockage :
gs://forgerock-openidm-audit-logs/openidm/. - Option de suppression des sources : sélectionnez l'option de votre choix (par exemple, Jamais).
- Cliquez sur Suivant, vérifiez, puis cliquez sur Envoyer.
Accorder des autorisations IAM
- Accédez à Cloud Storage > Buckets.
- Sélectionnez votre bucket, puis cliquez sur l'onglet Autorisations.
- Cliquez sur Accorder l'accès.
- Ajouter des comptes principaux : collez l'adresse e-mail du compte de service Google SecOps.
- Attribuer des rôles : sélectionnez Lecteur d'objets Storage.
- Cliquez sur Enregistrer.
Table de mappage UDM
| Champ de journal | Mappage UDM | Logique |
|---|---|---|
fluenttag_label, topic_label, context_roles_label |
additional.fields |
Paires clé-valeur pour le contexte. |
Via |
intermediary.hostname |
Nom d'hôte du proxy/de l'intermédiaire. |
x_forwarded_ip, caller.callerIps |
intermediary.ip |
Adresse IP de l'intermédiaire. |
timestamp |
metadata.event_timestamp |
Code temporel de l'événement. |
transactionId |
metadata.product_deployment_id |
ID de transaction unique. |
eventName |
metadata.product_event_type |
Nom de l'événement provenant de ForgeRock. |
_id |
metadata.product_log_id |
Identifiant unique du journal. |
request_method |
network.http.method |
Méthode HTTP utilisée. |
response.statusCode |
network.http.response_code |
Code d'état HTTP. |
user_agent |
network.http.user_agent |
Chaîne user-agent complète. |
client.ip, context.ipAddress |
principal.ip |
Adresse IP source de l'acteur. |
userId, principalData.0 |
principal.user.userid |
ID de l'utilisateur agissant. |
security_action |
security_result.action |
Décision de sécurité prise. |
level |
security_result.severity |
Niveau de gravité mappé. |
server.ip |
target.ip |
Adresse IP du système cible. |
http.request.path |
target.url |
URL/Chemin cible. |
| N/A | metadata.product_name |
Définissez-le sur ForgeRock OpenIDM. |
| N/A | metadata.vendor_name |
Définissez-le sur ForgeRock. |
elapsed_time" and "X-Content-Type-Options |
additional.fields |
Mappé à partir du journal des modifications |
trackingIds.0 |
metadata.product_log_id |
Mappé à partir du journal des modifications |
context.userRolesProperty", "context.authenticationId", and "context.authenticationIdProperty |
principal.user.attribute.roles |
Mappé à partir du journal des modifications |
context.component", "context.moduleId", and "context.queryId |
principal.resource.attribute.labels |
Mappé à partir du journal des modifications |
context.roles", "_normalized.fieldNames", and "_eventId |
additional.fields |
Mappé à partir du journal des modifications |
Journal des modifications
Afficher le journal des modifications pour ce parseur
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.