import json, os, sys S = json.loads(os.environ.get("INTEGRATION_SECRETS", "{}")) I = json.loads(os.environ.get("INTEGRATION_INPUTS", "{}")) def out(value): print(json.dumps(value, default=str)) def fail(message, **extra): payload = {"error": message} payload.update(extra) print(json.dumps(payload, default=str)) sys.exit(1) def as_bool(v): return v if isinstance(v, bool) else str(v).lower() in ("1", "true", "yes") def as_int(v, default=None): try: return int(v) except (TypeError, ValueError): return default def as_list(v): if isinstance(v, list): return v if v in (None, ""): return [] return [x.strip() for x in str(v).split(",") if x.strip()] try: from pycti import OpenCTIApiClient except ImportError as e: fail("The 'pycti' Python library is required for the OpenCTI integration. " "Install it on the execution host (engine): pip install pycti", detail=str(e)) def client(): base = str(S.get("base_url", "")).strip().rstrip("/") api_key = S.get("api_key") or (S.get("credentials") or {}).get("password") return OpenCTIApiClient(base, api_key, ssl_verify=not as_bool(S.get("insecure")), log_level="error") indicator_id = I.get("id") name = I.get("name") description = I.get("description") confidence = I.get("confidence") score = I.get("score") valid_from = I.get("valid_from") valid_until = I.get("valid_until") indicator_types = I.get("indicator_types") label_id = I.get("label_id") marking_id = I.get("marking_id") external_references_id = I.get("external_references_id") update_fields = [] if name: update_fields.append({"key": "name", "value": name}) if description: update_fields.append({"key": "description", "value": description}) if confidence: update_fields.append({"key": "confidence", "value": as_int(confidence)}) if score: update_fields.append({"key": "x_opencti_score", "value": as_int(score)}) if valid_from: update_fields.append({"key": "valid_from", "value": valid_from}) if valid_until: update_fields.append({"key": "valid_until", "value": valid_until}) if indicator_types: update_fields.append({"key": "indicator_types", "value": indicator_types.split(",")}) if label_id: update_fields.append({"key": "objectLabel", "value": label_id.split(",")}) if marking_id: update_fields.append({"key": "objectMarking", "value": marking_id.split(",")}) if external_references_id: update_fields.append({"key": "externalReferences", "value": external_references_id.split(",")}) mutation = """ mutation IndicatorEditionOverviewFieldPatchMutation($id: ID!, $input: [EditInput!]!, $commitMessage: String, $references: [String]) { indicatorFieldPatch(id: $id, input: $input, commitMessage: $commitMessage, references: $references) { id name confidence description valid_from valid_until x_opencti_score indicator_types } } """ variables = { "id": indicator_id, "input": update_fields, "commitMessage": None, "references": None, } try: result = client().query(mutation, variables) except Exception as e: fail("Can't update indicator in OpenCTI.", detail=str(e)) patched = result.get("data", {}).get("indicatorFieldPatch") if patched: out({ "id": patched.get("id"), "name": patched.get("name"), "validFrom": valid_from, "validUntil": valid_until, "message": "Indicator updated.", }) else: fail("Can't update indicator in OpenCTI.")