[{"data":1,"prerenderedAt":2242},["ShallowReactive",2],{"content-query-hWMyebFUlZ":3,"search-blog":1759,"search-docs":1954,"search-features":2188},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"author":10,"tags":11,"categories":17,"date":19,"layout":20,"excerpt":21,"body":46,"_type":1752,"_id":1753,"_source":1754,"_file":1755,"_stem":1756,"_extension":1757,"sitemap":1758},"/blog/guardduty-to-gcs-archival","blog",false,"","Archive AWS GuardDuty Findings to GCP Cloud Storage","Route AWS GuardDuty security findings to Google Cloud Storage using Webhook Relay Service Connections for long-term retention and cross-cloud analysis","Karolis Rusenas",[12,13,14,15,16],"aws","gcp","security","service-connections","guardduty",[18],"tutorials","2026-03-07 10:00:00","post",{"type":22,"children":23},"root",[24,32],{"type":25,"tag":26,"props":27,"children":28},"element","p",{},[29],{"type":30,"value":31},"text","AWS GuardDuty monitors your AWS accounts for malicious activity and unauthorized behavior. But what if your analytics stack lives in GCP? Maybe you run BigQuery for security analysis or Chronicle for SIEM. Getting GuardDuty findings into GCP usually means building custom Lambda functions, managing cross-cloud credentials, and maintaining glue code.",{"type":25,"tag":26,"props":33,"children":34},{},[35,37,44],{"type":30,"value":36},"Webhook Relay ",{"type":25,"tag":38,"props":39,"children":41},"a",{"href":40},"/docs/service-connections",[42],{"type":30,"value":43},"Service Connections",{"type":30,"value":45}," let you route GuardDuty findings to GCP Cloud Storage in minutes, no code required.",{"type":22,"children":47,"toc":1726},[48,52,61,68,73,83,88,93,99,145,151,158,171,213,225,233,239,244,288,293,316,321,400,405,437,442,448,453,480,661,681,687,700,706,740,746,793,799,804,810,873,879,915,921,946,958,993,1003,1046,1055,1060,1068,1073,1079,1085,1090,1111,1116,1122,1127,1135,1140,1146,1159,1460,1465,1471,1476,1628,1634,1644,1654,1664,1674,1680,1685,1703,1708,1720],{"type":25,"tag":26,"props":49,"children":50},{},[51],{"type":30,"value":31},{"type":25,"tag":26,"props":53,"children":54},{},[55,56,60],{"type":30,"value":36},{"type":25,"tag":38,"props":57,"children":58},{"href":40},[59],{"type":30,"value":43},{"type":30,"value":45},{"type":25,"tag":62,"props":63,"children":65},"h2",{"id":64},"architecture-overview",[66],{"type":30,"value":67},"Architecture Overview",{"type":25,"tag":26,"props":69,"children":70},{},[71],{"type":30,"value":72},"The data flow:",{"type":25,"tag":74,"props":75,"children":77},"pre",{"code":76},"AWS GuardDuty → EventBridge → SQS Queue → Webhook Relay → GCP Cloud Storage\n",[78],{"type":25,"tag":79,"props":80,"children":81},"code",{"__ignoreMap":7},[82],{"type":30,"value":76},{"type":25,"tag":26,"props":84,"children":85},{},[86],{"type":30,"value":87},"GuardDuty publishes findings to Amazon EventBridge. An EventBridge rule routes them to an SQS queue. Webhook Relay polls the queue and stores each finding as a JSON file in your GCS bucket.",{"type":25,"tag":26,"props":89,"children":90},{},[91],{"type":30,"value":92},"You can also publish to AWS S3 if you prefer, just in this case we want to access them through BigQuery afterwards.",{"type":25,"tag":62,"props":94,"children":96},{"id":95},"why-this-approach",[97],{"type":30,"value":98},"Why This Approach?",{"type":25,"tag":100,"props":101,"children":102},"ul",{},[103,115,125,135],{"type":25,"tag":104,"props":105,"children":106},"li",{},[107,113],{"type":25,"tag":108,"props":109,"children":110},"strong",{},[111],{"type":30,"value":112},"No custom code.",{"type":30,"value":114}," No Lambda functions to maintain, no credential rotation scripts, no deployment pipelines.",{"type":25,"tag":104,"props":116,"children":117},{},[118,123],{"type":25,"tag":108,"props":119,"children":120},{},[121],{"type":30,"value":122},"Long-term retention.",{"type":30,"value":124}," GCS lifecycle policies move findings to Coldline or Archive storage automatically. Keep years of security data cheaply.",{"type":25,"tag":104,"props":126,"children":127},{},[128,133],{"type":25,"tag":108,"props":129,"children":130},{},[131],{"type":30,"value":132},"Analytics-ready.",{"type":30,"value":134}," BigQuery can query your findings directly from GCS. Build dashboards, run threat hunting queries, or feed data into Chronicle.",{"type":25,"tag":104,"props":136,"children":137},{},[138,143],{"type":25,"tag":108,"props":139,"children":140},{},[141],{"type":30,"value":142},"Reliable delivery.",{"type":30,"value":144}," SQS provides durable message queuing. Webhook Relay handles retries.",{"type":25,"tag":62,"props":146,"children":148},{"id":147},"aws-setup",[149],{"type":30,"value":150},"AWS Setup",{"type":25,"tag":152,"props":153,"children":155},"h3",{"id":154},"step-1-create-an-sqs-queue",[156],{"type":30,"value":157},"Step 1: Create an SQS Queue",{"type":25,"tag":26,"props":159,"children":160},{},[161,163,169],{"type":30,"value":162},"First, create an ",{"type":25,"tag":38,"props":164,"children":166},{"href":165},"/docs/service-connections/aws_sqs",[167],{"type":30,"value":168},"SQS queue",{"type":30,"value":170}," to receive GuardDuty findings:",{"type":25,"tag":172,"props":173,"children":174},"ol",{},[175,185,197,208],{"type":25,"tag":104,"props":176,"children":177},{},[178,180],{"type":30,"value":179},"Go to ",{"type":25,"tag":108,"props":181,"children":182},{},[183],{"type":30,"value":184},"AWS Console → SQS → Create queue",{"type":25,"tag":104,"props":186,"children":187},{},[188,190,195],{"type":30,"value":189},"Choose ",{"type":25,"tag":108,"props":191,"children":192},{},[193],{"type":30,"value":194},"Standard",{"type":30,"value":196}," queue type",{"type":25,"tag":104,"props":198,"children":199},{},[200,202],{"type":30,"value":201},"Name it ",{"type":25,"tag":79,"props":203,"children":205},{"className":204},[],[206],{"type":30,"value":207},"guardduty-findings",{"type":25,"tag":104,"props":209,"children":210},{},[211],{"type":30,"value":212},"Keep default settings and create the queue",{"type":25,"tag":26,"props":214,"children":215},{},[216,218,223],{"type":30,"value":217},"Copy the ",{"type":25,"tag":108,"props":219,"children":220},{},[221],{"type":30,"value":222},"Queue URL",{"type":30,"value":224},". It looks like:",{"type":25,"tag":74,"props":226,"children":228},{"code":227},"https://sqs.us-east-1.amazonaws.com/123456789012/guardduty-findings\n",[229],{"type":25,"tag":79,"props":230,"children":231},{"__ignoreMap":7},[232],{"type":30,"value":227},{"type":25,"tag":152,"props":234,"children":236},{"id":235},"step-2-create-an-eventbridge-rule",[237],{"type":30,"value":238},"Step 2: Create an EventBridge Rule",{"type":25,"tag":26,"props":240,"children":241},{},[242],{"type":30,"value":243},"EventBridge routes GuardDuty findings to your SQS queue:",{"type":25,"tag":172,"props":245,"children":246},{},[247,256,267,278],{"type":25,"tag":104,"props":248,"children":249},{},[250,251],{"type":30,"value":179},{"type":25,"tag":108,"props":252,"children":253},{},[254],{"type":30,"value":255},"AWS Console → EventBridge → Rules → Create rule",{"type":25,"tag":104,"props":257,"children":258},{},[259,261],{"type":30,"value":260},"Name: ",{"type":25,"tag":79,"props":262,"children":264},{"className":263},[],[265],{"type":30,"value":266},"guardduty-to-sqs",{"type":25,"tag":104,"props":268,"children":269},{},[270,272],{"type":30,"value":271},"Event bus: ",{"type":25,"tag":79,"props":273,"children":275},{"className":274},[],[276],{"type":30,"value":277},"default",{"type":25,"tag":104,"props":279,"children":280},{},[281,283],{"type":30,"value":282},"Rule type: ",{"type":25,"tag":108,"props":284,"children":285},{},[286],{"type":30,"value":287},"Rule with an event pattern",{"type":25,"tag":26,"props":289,"children":290},{},[291],{"type":30,"value":292},"For the event pattern, select:",{"type":25,"tag":100,"props":294,"children":295},{},[296,306],{"type":25,"tag":104,"props":297,"children":298},{},[299,301],{"type":30,"value":300},"AWS service: ",{"type":25,"tag":108,"props":302,"children":303},{},[304],{"type":30,"value":305},"GuardDuty",{"type":25,"tag":104,"props":307,"children":308},{},[309,311],{"type":30,"value":310},"Event type: ",{"type":25,"tag":108,"props":312,"children":313},{},[314],{"type":30,"value":315},"GuardDuty Finding",{"type":25,"tag":26,"props":317,"children":318},{},[319],{"type":30,"value":320},"Or use this custom pattern to capture all GuardDuty findings:",{"type":25,"tag":74,"props":322,"children":326},{"code":323,"language":324,"meta":7,"className":325,"style":7},"{\n  \"source\": [\"aws.guardduty\"],\n  \"detail-type\": [\"GuardDuty Finding\"]\n}\n","json","language-json shiki shiki-themes github-dark",[327],{"type":25,"tag":79,"props":328,"children":329},{"__ignoreMap":7},[330,342,368,391],{"type":25,"tag":331,"props":332,"children":335},"span",{"class":333,"line":334},"line",1,[336],{"type":25,"tag":331,"props":337,"children":339},{"style":338},"--shiki-default:#E1E4E8",[340],{"type":30,"value":341},"{\n",{"type":25,"tag":331,"props":343,"children":345},{"class":333,"line":344},2,[346,352,357,363],{"type":25,"tag":331,"props":347,"children":349},{"style":348},"--shiki-default:#79B8FF",[350],{"type":30,"value":351},"  \"source\"",{"type":25,"tag":331,"props":353,"children":354},{"style":338},[355],{"type":30,"value":356},": [",{"type":25,"tag":331,"props":358,"children":360},{"style":359},"--shiki-default:#9ECBFF",[361],{"type":30,"value":362},"\"aws.guardduty\"",{"type":25,"tag":331,"props":364,"children":365},{"style":338},[366],{"type":30,"value":367},"],\n",{"type":25,"tag":331,"props":369,"children":371},{"class":333,"line":370},3,[372,377,381,386],{"type":25,"tag":331,"props":373,"children":374},{"style":348},[375],{"type":30,"value":376},"  \"detail-type\"",{"type":25,"tag":331,"props":378,"children":379},{"style":338},[380],{"type":30,"value":356},{"type":25,"tag":331,"props":382,"children":383},{"style":359},[384],{"type":30,"value":385},"\"GuardDuty Finding\"",{"type":25,"tag":331,"props":387,"children":388},{"style":338},[389],{"type":30,"value":390},"]\n",{"type":25,"tag":331,"props":392,"children":394},{"class":333,"line":393},4,[395],{"type":25,"tag":331,"props":396,"children":397},{"style":338},[398],{"type":30,"value":399},"}\n",{"type":25,"tag":26,"props":401,"children":402},{},[403],{"type":30,"value":404},"For the target:",{"type":25,"tag":100,"props":406,"children":407},{},[408,418,427],{"type":25,"tag":104,"props":409,"children":410},{},[411,413],{"type":30,"value":412},"Target type: ",{"type":25,"tag":108,"props":414,"children":415},{},[416],{"type":30,"value":417},"AWS service",{"type":25,"tag":104,"props":419,"children":420},{},[421,423],{"type":30,"value":422},"Select target: ",{"type":25,"tag":108,"props":424,"children":425},{},[426],{"type":30,"value":168},{"type":25,"tag":104,"props":428,"children":429},{},[430,432],{"type":30,"value":431},"Queue: ",{"type":25,"tag":79,"props":433,"children":435},{"className":434},[],[436],{"type":30,"value":207},{"type":25,"tag":26,"props":438,"children":439},{},[440],{"type":30,"value":441},"Create the rule. EventBridge will now route all GuardDuty findings to your SQS queue.",{"type":25,"tag":152,"props":443,"children":445},{"id":444},"step-3-create-an-iam-user-for-webhook-relay",[446],{"type":30,"value":447},"Step 3: Create an IAM User for Webhook Relay",{"type":25,"tag":26,"props":449,"children":450},{},[451],{"type":30,"value":452},"Webhook Relay needs credentials to poll your SQS queue:",{"type":25,"tag":172,"props":454,"children":455},{},[456,465,475],{"type":25,"tag":104,"props":457,"children":458},{},[459,460],{"type":30,"value":179},{"type":25,"tag":108,"props":461,"children":462},{},[463],{"type":30,"value":464},"AWS Console → IAM → Users → Create user",{"type":25,"tag":104,"props":466,"children":467},{},[468,469],{"type":30,"value":260},{"type":25,"tag":79,"props":470,"children":472},{"className":471},[],[473],{"type":30,"value":474},"webhookrelay-sqs-reader",{"type":25,"tag":104,"props":476,"children":477},{},[478],{"type":30,"value":479},"Attach a policy with these permissions:",{"type":25,"tag":74,"props":481,"children":483},{"code":482,"language":324,"meta":7,"className":325,"style":7},"{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"sqs:ReceiveMessage\",\n        \"sqs:DeleteMessage\",\n        \"sqs:GetQueueAttributes\"\n      ],\n      \"Resource\": \"arn:aws:sqs:us-east-1:123456789012:guardduty-findings\"\n    }\n  ]\n}\n",[484],{"type":25,"tag":79,"props":485,"children":486},{"__ignoreMap":7},[487,494,517,530,538,560,573,586,599,608,617,635,644,653],{"type":25,"tag":331,"props":488,"children":489},{"class":333,"line":334},[490],{"type":25,"tag":331,"props":491,"children":492},{"style":338},[493],{"type":30,"value":341},{"type":25,"tag":331,"props":495,"children":496},{"class":333,"line":344},[497,502,507,512],{"type":25,"tag":331,"props":498,"children":499},{"style":348},[500],{"type":30,"value":501},"  \"Version\"",{"type":25,"tag":331,"props":503,"children":504},{"style":338},[505],{"type":30,"value":506},": ",{"type":25,"tag":331,"props":508,"children":509},{"style":359},[510],{"type":30,"value":511},"\"2012-10-17\"",{"type":25,"tag":331,"props":513,"children":514},{"style":338},[515],{"type":30,"value":516},",\n",{"type":25,"tag":331,"props":518,"children":519},{"class":333,"line":370},[520,525],{"type":25,"tag":331,"props":521,"children":522},{"style":348},[523],{"type":30,"value":524},"  \"Statement\"",{"type":25,"tag":331,"props":526,"children":527},{"style":338},[528],{"type":30,"value":529},": [\n",{"type":25,"tag":331,"props":531,"children":532},{"class":333,"line":393},[533],{"type":25,"tag":331,"props":534,"children":535},{"style":338},[536],{"type":30,"value":537},"    {\n",{"type":25,"tag":331,"props":539,"children":541},{"class":333,"line":540},5,[542,547,551,556],{"type":25,"tag":331,"props":543,"children":544},{"style":348},[545],{"type":30,"value":546},"      \"Effect\"",{"type":25,"tag":331,"props":548,"children":549},{"style":338},[550],{"type":30,"value":506},{"type":25,"tag":331,"props":552,"children":553},{"style":359},[554],{"type":30,"value":555},"\"Allow\"",{"type":25,"tag":331,"props":557,"children":558},{"style":338},[559],{"type":30,"value":516},{"type":25,"tag":331,"props":561,"children":563},{"class":333,"line":562},6,[564,569],{"type":25,"tag":331,"props":565,"children":566},{"style":348},[567],{"type":30,"value":568},"      \"Action\"",{"type":25,"tag":331,"props":570,"children":571},{"style":338},[572],{"type":30,"value":529},{"type":25,"tag":331,"props":574,"children":576},{"class":333,"line":575},7,[577,582],{"type":25,"tag":331,"props":578,"children":579},{"style":359},[580],{"type":30,"value":581},"        \"sqs:ReceiveMessage\"",{"type":25,"tag":331,"props":583,"children":584},{"style":338},[585],{"type":30,"value":516},{"type":25,"tag":331,"props":587,"children":589},{"class":333,"line":588},8,[590,595],{"type":25,"tag":331,"props":591,"children":592},{"style":359},[593],{"type":30,"value":594},"        \"sqs:DeleteMessage\"",{"type":25,"tag":331,"props":596,"children":597},{"style":338},[598],{"type":30,"value":516},{"type":25,"tag":331,"props":600,"children":602},{"class":333,"line":601},9,[603],{"type":25,"tag":331,"props":604,"children":605},{"style":359},[606],{"type":30,"value":607},"        \"sqs:GetQueueAttributes\"\n",{"type":25,"tag":331,"props":609,"children":611},{"class":333,"line":610},10,[612],{"type":25,"tag":331,"props":613,"children":614},{"style":338},[615],{"type":30,"value":616},"      ],\n",{"type":25,"tag":331,"props":618,"children":620},{"class":333,"line":619},11,[621,626,630],{"type":25,"tag":331,"props":622,"children":623},{"style":348},[624],{"type":30,"value":625},"      \"Resource\"",{"type":25,"tag":331,"props":627,"children":628},{"style":338},[629],{"type":30,"value":506},{"type":25,"tag":331,"props":631,"children":632},{"style":359},[633],{"type":30,"value":634},"\"arn:aws:sqs:us-east-1:123456789012:guardduty-findings\"\n",{"type":25,"tag":331,"props":636,"children":638},{"class":333,"line":637},12,[639],{"type":25,"tag":331,"props":640,"children":641},{"style":338},[642],{"type":30,"value":643},"    }\n",{"type":25,"tag":331,"props":645,"children":647},{"class":333,"line":646},13,[648],{"type":25,"tag":331,"props":649,"children":650},{"style":338},[651],{"type":30,"value":652},"  ]\n",{"type":25,"tag":331,"props":654,"children":656},{"class":333,"line":655},14,[657],{"type":25,"tag":331,"props":658,"children":659},{"style":338},[660],{"type":30,"value":399},{"type":25,"tag":172,"props":662,"children":663},{"start":393},[664],{"type":25,"tag":104,"props":665,"children":666},{},[667,669,674,676],{"type":30,"value":668},"Create an access key and save the ",{"type":25,"tag":108,"props":670,"children":671},{},[672],{"type":30,"value":673},"Access Key ID",{"type":30,"value":675}," and ",{"type":25,"tag":108,"props":677,"children":678},{},[679],{"type":30,"value":680},"Secret Access Key",{"type":25,"tag":62,"props":682,"children":684},{"id":683},"gcp-setup",[685],{"type":30,"value":686},"GCP Setup",{"type":25,"tag":26,"props":688,"children":689},{},[690,692,698],{"type":30,"value":691},"We will be using ",{"type":25,"tag":38,"props":693,"children":695},{"href":694},"/docs/service-connections/gcp_gcs",[696],{"type":30,"value":697},"GCP GCS service connection",{"type":30,"value":699}," for this.",{"type":25,"tag":152,"props":701,"children":703},{"id":702},"step-1-create-a-gcs-bucket",[704],{"type":30,"value":705},"Step 1: Create a GCS Bucket",{"type":25,"tag":172,"props":707,"children":708},{},[709,718,730,735],{"type":25,"tag":104,"props":710,"children":711},{},[712,713],{"type":30,"value":179},{"type":25,"tag":108,"props":714,"children":715},{},[716],{"type":30,"value":717},"GCP Console → Cloud Storage → Create bucket",{"type":25,"tag":104,"props":719,"children":720},{},[721,722,728],{"type":30,"value":260},{"type":25,"tag":79,"props":723,"children":725},{"className":724},[],[726],{"type":30,"value":727},"guardduty-archive",{"type":30,"value":729}," (or your preferred name)",{"type":25,"tag":104,"props":731,"children":732},{},[733],{"type":30,"value":734},"Choose your region and storage class",{"type":25,"tag":104,"props":736,"children":737},{},[738],{"type":30,"value":739},"Create the bucket",{"type":25,"tag":152,"props":741,"children":743},{"id":742},"step-2-create-a-service-account",[744],{"type":30,"value":745},"Step 2: Create a Service Account",{"type":25,"tag":172,"props":747,"children":748},{},[749,758,768,788],{"type":25,"tag":104,"props":750,"children":751},{},[752,753],{"type":30,"value":179},{"type":25,"tag":108,"props":754,"children":755},{},[756],{"type":30,"value":757},"GCP Console → IAM → Service Accounts → Create",{"type":25,"tag":104,"props":759,"children":760},{},[761,762],{"type":30,"value":260},{"type":25,"tag":79,"props":763,"children":765},{"className":764},[],[766],{"type":30,"value":767},"webhookrelay-gcs-writer",{"type":25,"tag":104,"props":769,"children":770},{},[771,773,778,780,786],{"type":30,"value":772},"Grant the role: ",{"type":25,"tag":108,"props":774,"children":775},{},[776],{"type":30,"value":777},"Storage Object Creator",{"type":30,"value":779}," (",{"type":25,"tag":79,"props":781,"children":783},{"className":782},[],[784],{"type":30,"value":785},"roles/storage.objectCreator",{"type":30,"value":787},")",{"type":25,"tag":104,"props":789,"children":790},{},[791],{"type":30,"value":792},"Create a JSON key and download it",{"type":25,"tag":62,"props":794,"children":796},{"id":795},"webhook-relay-setup",[797],{"type":30,"value":798},"Webhook Relay Setup",{"type":25,"tag":26,"props":800,"children":801},{},[802],{"type":30,"value":803},"Connect both clouds through Webhook Relay.",{"type":25,"tag":152,"props":805,"children":807},{"id":806},"step-1-add-aws-service-connection",[808],{"type":30,"value":809},"Step 1: Add AWS Service Connection",{"type":25,"tag":172,"props":811,"children":812},{},[813,825,835,845,861],{"type":25,"tag":104,"props":814,"children":815},{},[816,817],{"type":30,"value":179},{"type":25,"tag":38,"props":818,"children":822},{"href":819,"rel":820},"https://my.webhookrelay.com/service-connections",[821],"nofollow",[823],{"type":30,"value":824},"Webhook Relay Service Connections",{"type":25,"tag":104,"props":826,"children":827},{},[828,830],{"type":30,"value":829},"Click ",{"type":25,"tag":108,"props":831,"children":832},{},[833],{"type":30,"value":834},"Add Connection",{"type":25,"tag":104,"props":836,"children":837},{},[838,840],{"type":30,"value":839},"Select ",{"type":25,"tag":108,"props":841,"children":842},{},[843],{"type":30,"value":844},"AWS",{"type":25,"tag":104,"props":846,"children":847},{},[848,850],{"type":30,"value":849},"Enter your IAM user credentials:\n",{"type":25,"tag":100,"props":851,"children":852},{},[853,857],{"type":25,"tag":104,"props":854,"children":855},{},[856],{"type":30,"value":673},{"type":25,"tag":104,"props":858,"children":859},{},[860],{"type":30,"value":680},{"type":25,"tag":104,"props":862,"children":863},{},[864,865,871],{"type":30,"value":201},{"type":25,"tag":79,"props":866,"children":868},{"className":867},[],[869],{"type":30,"value":870},"aws-guardduty",{"type":30,"value":872}," and save",{"type":25,"tag":152,"props":874,"children":876},{"id":875},"step-2-add-gcp-service-connection",[877],{"type":30,"value":878},"Step 2: Add GCP Service Connection",{"type":25,"tag":172,"props":880,"children":881},{},[882,890,899,904],{"type":25,"tag":104,"props":883,"children":884},{},[885,886],{"type":30,"value":829},{"type":25,"tag":108,"props":887,"children":888},{},[889],{"type":30,"value":834},{"type":25,"tag":104,"props":891,"children":892},{},[893,894],{"type":30,"value":839},{"type":25,"tag":108,"props":895,"children":896},{},[897],{"type":30,"value":898},"GCP",{"type":25,"tag":104,"props":900,"children":901},{},[902],{"type":30,"value":903},"Paste the contents of your service account JSON key",{"type":25,"tag":104,"props":905,"children":906},{},[907,908,914],{"type":30,"value":201},{"type":25,"tag":79,"props":909,"children":911},{"className":910},[],[912],{"type":30,"value":913},"gcp-storage",{"type":30,"value":872},{"type":25,"tag":152,"props":916,"children":918},{"id":917},"step-3-create-a-bucket-with-sqs-input-and-gcs-output",[919],{"type":30,"value":920},"Step 3: Create a Bucket with SQS Input and GCS Output",{"type":25,"tag":172,"props":922,"children":923},{},[924,937],{"type":25,"tag":104,"props":925,"children":926},{},[927,928,935],{"type":30,"value":179},{"type":25,"tag":38,"props":929,"children":932},{"href":930,"rel":931},"https://my.webhookrelay.com/buckets",[821],[933],{"type":30,"value":934},"Buckets",{"type":30,"value":936}," and create a new bucket",{"type":25,"tag":104,"props":938,"children":939},{},[940,941],{"type":30,"value":201},{"type":25,"tag":79,"props":942,"children":944},{"className":943},[],[945],{"type":30,"value":727},{"type":25,"tag":26,"props":947,"children":948},{},[949,951,956],{"type":30,"value":950},"Add the ",{"type":25,"tag":108,"props":952,"children":953},{},[954],{"type":30,"value":955},"SQS Input",{"type":30,"value":957},":",{"type":25,"tag":172,"props":959,"children":960},{},[961,970,982],{"type":25,"tag":104,"props":962,"children":963},{},[964,965],{"type":30,"value":829},{"type":25,"tag":108,"props":966,"children":967},{},[968],{"type":30,"value":969},"Add Input → AWS SQS",{"type":25,"tag":104,"props":971,"children":972},{},[973,975,980],{"type":30,"value":974},"Select your ",{"type":25,"tag":79,"props":976,"children":978},{"className":977},[],[979],{"type":30,"value":870},{"type":30,"value":981}," connection",{"type":25,"tag":104,"props":983,"children":984},{},[985,987],{"type":30,"value":986},"Enter the queue URL: ",{"type":25,"tag":79,"props":988,"children":990},{"className":989},[],[991],{"type":30,"value":992},"https://sqs.us-east-1.amazonaws.com/123456789012/guardduty-findings",{"type":25,"tag":26,"props":994,"children":995},{},[996,997,1002],{"type":30,"value":950},{"type":25,"tag":108,"props":998,"children":999},{},[1000],{"type":30,"value":1001},"GCS Output",{"type":30,"value":957},{"type":25,"tag":172,"props":1004,"children":1005},{},[1006,1015,1025,1035],{"type":25,"tag":104,"props":1007,"children":1008},{},[1009,1010],{"type":30,"value":829},{"type":25,"tag":108,"props":1011,"children":1012},{},[1013],{"type":30,"value":1014},"Add Output → GCP Cloud Storage",{"type":25,"tag":104,"props":1016,"children":1017},{},[1018,1019,1024],{"type":30,"value":974},{"type":25,"tag":79,"props":1020,"children":1022},{"className":1021},[],[1023],{"type":30,"value":913},{"type":30,"value":981},{"type":25,"tag":104,"props":1026,"children":1027},{},[1028,1030],{"type":30,"value":1029},"Bucket name: ",{"type":25,"tag":79,"props":1031,"children":1033},{"className":1032},[],[1034],{"type":30,"value":727},{"type":25,"tag":104,"props":1036,"children":1037},{},[1038,1040],{"type":30,"value":1039},"Prefix: ",{"type":25,"tag":79,"props":1041,"children":1043},{"className":1042},[],[1044],{"type":30,"value":1045},"findings/",{"type":25,"tag":26,"props":1047,"children":1048},{},[1049],{"type":25,"tag":1050,"props":1051,"children":1054},"img",{"alt":1052,"src":1053},"Selecting your output","/images/blog/aws_guard_duty_gcs/gcs_bucket.png",[],{"type":25,"tag":26,"props":1056,"children":1057},{},[1058],{"type":30,"value":1059},"And then configure the bucket:",{"type":25,"tag":26,"props":1061,"children":1062},{},[1063],{"type":25,"tag":1050,"props":1064,"children":1067},{"alt":1065,"src":1066},"Output configuration","/images/blog/aws_guard_duty_gcs/output.png",[],{"type":25,"tag":26,"props":1069,"children":1070},{},[1071],{"type":30,"value":1072},"Webhook Relay will now poll your SQS queue and store each GuardDuty finding in GCS.",{"type":25,"tag":62,"props":1074,"children":1076},{"id":1075},"verify-it-works",[1077],{"type":30,"value":1078},"Verify It Works",{"type":25,"tag":152,"props":1080,"children":1082},{"id":1081},"generate-a-test-finding",[1083],{"type":30,"value":1084},"Generate a Test Finding",{"type":25,"tag":26,"props":1086,"children":1087},{},[1088],{"type":30,"value":1089},"GuardDuty can generate sample findings for testing:",{"type":25,"tag":172,"props":1091,"children":1092},{},[1093,1102],{"type":25,"tag":104,"props":1094,"children":1095},{},[1096,1097],{"type":30,"value":179},{"type":25,"tag":108,"props":1098,"children":1099},{},[1100],{"type":30,"value":1101},"AWS Console → GuardDuty → Settings",{"type":25,"tag":104,"props":1103,"children":1104},{},[1105,1106],{"type":30,"value":829},{"type":25,"tag":108,"props":1107,"children":1108},{},[1109],{"type":30,"value":1110},"Generate sample findings",{"type":25,"tag":26,"props":1112,"children":1113},{},[1114],{"type":30,"value":1115},"This creates test findings that flow through your pipeline.",{"type":25,"tag":152,"props":1117,"children":1119},{"id":1118},"check-gcs",[1120],{"type":30,"value":1121},"Check GCS",{"type":25,"tag":26,"props":1123,"children":1124},{},[1125],{"type":30,"value":1126},"After a minute or two, check your GCS bucket. You should see files at:",{"type":25,"tag":74,"props":1128,"children":1130},{"code":1129},"findings/2026/03/06/\u003Cfinding-id>.json\n",[1131],{"type":25,"tag":79,"props":1132,"children":1133},{"__ignoreMap":7},[1134],{"type":30,"value":1129},{"type":25,"tag":26,"props":1136,"children":1137},{},[1138],{"type":30,"value":1139},"Each file contains the full GuardDuty finding with all metadata, severity scores, and resource details.",{"type":25,"tag":62,"props":1141,"children":1143},{"id":1142},"optional-transform-findings-before-storage",[1144],{"type":30,"value":1145},"Optional: Transform Findings Before Storage",{"type":25,"tag":26,"props":1147,"children":1148},{},[1149,1151,1157],{"type":30,"value":1150},"To reshape the data or extract specific fields before storing, add a ",{"type":25,"tag":38,"props":1152,"children":1154},{"href":1153},"/docs/webhooks/functions",[1155],{"type":30,"value":1156},"Function",{"type":30,"value":1158}," to your bucket:",{"type":25,"tag":74,"props":1160,"children":1164},{"code":1161,"language":1162,"meta":7,"className":1163,"style":7},"const event = JSON.parse(r.body)\nconst finding = event.detail\n\n// Create a simplified structure for analysis\nconst archived = {\n  id: finding.id,\n  severity: finding.severity,\n  type: finding.type,\n  title: finding.title,\n  description: finding.description,\n  region: finding.region,\n  accountId: finding.accountId,\n  resourceType: finding.resource.resourceType,\n  createdAt: finding.createdAt,\n  updatedAt: finding.updatedAt,\n  // Add custom fields\n  archived_at: new Date().toISOString(),\n  source: \"aws-guardduty\"\n}\n\nr.setBody(JSON.stringify(archived))\n","javascript","language-javascript shiki shiki-themes github-dark",[1165],{"type":25,"tag":79,"props":1166,"children":1167},{"__ignoreMap":7},[1168,1208,1229,1238,1247,1268,1276,1284,1292,1300,1308,1316,1324,1332,1340,1349,1358,1392,1406,1414,1422],{"type":25,"tag":331,"props":1169,"children":1170},{"class":333,"line":334},[1171,1177,1182,1187,1192,1197,1203],{"type":25,"tag":331,"props":1172,"children":1174},{"style":1173},"--shiki-default:#F97583",[1175],{"type":30,"value":1176},"const",{"type":25,"tag":331,"props":1178,"children":1179},{"style":348},[1180],{"type":30,"value":1181}," event",{"type":25,"tag":331,"props":1183,"children":1184},{"style":1173},[1185],{"type":30,"value":1186}," =",{"type":25,"tag":331,"props":1188,"children":1189},{"style":348},[1190],{"type":30,"value":1191}," JSON",{"type":25,"tag":331,"props":1193,"children":1194},{"style":338},[1195],{"type":30,"value":1196},".",{"type":25,"tag":331,"props":1198,"children":1200},{"style":1199},"--shiki-default:#B392F0",[1201],{"type":30,"value":1202},"parse",{"type":25,"tag":331,"props":1204,"children":1205},{"style":338},[1206],{"type":30,"value":1207},"(r.body)\n",{"type":25,"tag":331,"props":1209,"children":1210},{"class":333,"line":344},[1211,1215,1220,1224],{"type":25,"tag":331,"props":1212,"children":1213},{"style":1173},[1214],{"type":30,"value":1176},{"type":25,"tag":331,"props":1216,"children":1217},{"style":348},[1218],{"type":30,"value":1219}," finding",{"type":25,"tag":331,"props":1221,"children":1222},{"style":1173},[1223],{"type":30,"value":1186},{"type":25,"tag":331,"props":1225,"children":1226},{"style":338},[1227],{"type":30,"value":1228}," event.detail\n",{"type":25,"tag":331,"props":1230,"children":1231},{"class":333,"line":370},[1232],{"type":25,"tag":331,"props":1233,"children":1235},{"emptyLinePlaceholder":1234},true,[1236],{"type":30,"value":1237},"\n",{"type":25,"tag":331,"props":1239,"children":1240},{"class":333,"line":393},[1241],{"type":25,"tag":331,"props":1242,"children":1244},{"style":1243},"--shiki-default:#6A737D",[1245],{"type":30,"value":1246},"// Create a simplified structure for analysis\n",{"type":25,"tag":331,"props":1248,"children":1249},{"class":333,"line":540},[1250,1254,1259,1263],{"type":25,"tag":331,"props":1251,"children":1252},{"style":1173},[1253],{"type":30,"value":1176},{"type":25,"tag":331,"props":1255,"children":1256},{"style":348},[1257],{"type":30,"value":1258}," archived",{"type":25,"tag":331,"props":1260,"children":1261},{"style":1173},[1262],{"type":30,"value":1186},{"type":25,"tag":331,"props":1264,"children":1265},{"style":338},[1266],{"type":30,"value":1267}," {\n",{"type":25,"tag":331,"props":1269,"children":1270},{"class":333,"line":562},[1271],{"type":25,"tag":331,"props":1272,"children":1273},{"style":338},[1274],{"type":30,"value":1275},"  id: finding.id,\n",{"type":25,"tag":331,"props":1277,"children":1278},{"class":333,"line":575},[1279],{"type":25,"tag":331,"props":1280,"children":1281},{"style":338},[1282],{"type":30,"value":1283},"  severity: finding.severity,\n",{"type":25,"tag":331,"props":1285,"children":1286},{"class":333,"line":588},[1287],{"type":25,"tag":331,"props":1288,"children":1289},{"style":338},[1290],{"type":30,"value":1291},"  type: finding.type,\n",{"type":25,"tag":331,"props":1293,"children":1294},{"class":333,"line":601},[1295],{"type":25,"tag":331,"props":1296,"children":1297},{"style":338},[1298],{"type":30,"value":1299},"  title: finding.title,\n",{"type":25,"tag":331,"props":1301,"children":1302},{"class":333,"line":610},[1303],{"type":25,"tag":331,"props":1304,"children":1305},{"style":338},[1306],{"type":30,"value":1307},"  description: finding.description,\n",{"type":25,"tag":331,"props":1309,"children":1310},{"class":333,"line":619},[1311],{"type":25,"tag":331,"props":1312,"children":1313},{"style":338},[1314],{"type":30,"value":1315},"  region: finding.region,\n",{"type":25,"tag":331,"props":1317,"children":1318},{"class":333,"line":637},[1319],{"type":25,"tag":331,"props":1320,"children":1321},{"style":338},[1322],{"type":30,"value":1323},"  accountId: finding.accountId,\n",{"type":25,"tag":331,"props":1325,"children":1326},{"class":333,"line":646},[1327],{"type":25,"tag":331,"props":1328,"children":1329},{"style":338},[1330],{"type":30,"value":1331},"  resourceType: finding.resource.resourceType,\n",{"type":25,"tag":331,"props":1333,"children":1334},{"class":333,"line":655},[1335],{"type":25,"tag":331,"props":1336,"children":1337},{"style":338},[1338],{"type":30,"value":1339},"  createdAt: finding.createdAt,\n",{"type":25,"tag":331,"props":1341,"children":1343},{"class":333,"line":1342},15,[1344],{"type":25,"tag":331,"props":1345,"children":1346},{"style":338},[1347],{"type":30,"value":1348},"  updatedAt: finding.updatedAt,\n",{"type":25,"tag":331,"props":1350,"children":1352},{"class":333,"line":1351},16,[1353],{"type":25,"tag":331,"props":1354,"children":1355},{"style":1243},[1356],{"type":30,"value":1357},"  // Add custom fields\n",{"type":25,"tag":331,"props":1359,"children":1361},{"class":333,"line":1360},17,[1362,1367,1372,1377,1382,1387],{"type":25,"tag":331,"props":1363,"children":1364},{"style":338},[1365],{"type":30,"value":1366},"  archived_at: ",{"type":25,"tag":331,"props":1368,"children":1369},{"style":1173},[1370],{"type":30,"value":1371},"new",{"type":25,"tag":331,"props":1373,"children":1374},{"style":1199},[1375],{"type":30,"value":1376}," Date",{"type":25,"tag":331,"props":1378,"children":1379},{"style":338},[1380],{"type":30,"value":1381},"().",{"type":25,"tag":331,"props":1383,"children":1384},{"style":1199},[1385],{"type":30,"value":1386},"toISOString",{"type":25,"tag":331,"props":1388,"children":1389},{"style":338},[1390],{"type":30,"value":1391},"(),\n",{"type":25,"tag":331,"props":1393,"children":1395},{"class":333,"line":1394},18,[1396,1401],{"type":25,"tag":331,"props":1397,"children":1398},{"style":338},[1399],{"type":30,"value":1400},"  source: ",{"type":25,"tag":331,"props":1402,"children":1403},{"style":359},[1404],{"type":30,"value":1405},"\"aws-guardduty\"\n",{"type":25,"tag":331,"props":1407,"children":1409},{"class":333,"line":1408},19,[1410],{"type":25,"tag":331,"props":1411,"children":1412},{"style":338},[1413],{"type":30,"value":399},{"type":25,"tag":331,"props":1415,"children":1417},{"class":333,"line":1416},20,[1418],{"type":25,"tag":331,"props":1419,"children":1420},{"emptyLinePlaceholder":1234},[1421],{"type":30,"value":1237},{"type":25,"tag":331,"props":1423,"children":1425},{"class":333,"line":1424},21,[1426,1431,1436,1441,1446,1450,1455],{"type":25,"tag":331,"props":1427,"children":1428},{"style":338},[1429],{"type":30,"value":1430},"r.",{"type":25,"tag":331,"props":1432,"children":1433},{"style":1199},[1434],{"type":30,"value":1435},"setBody",{"type":25,"tag":331,"props":1437,"children":1438},{"style":338},[1439],{"type":30,"value":1440},"(",{"type":25,"tag":331,"props":1442,"children":1443},{"style":348},[1444],{"type":30,"value":1445},"JSON",{"type":25,"tag":331,"props":1447,"children":1448},{"style":338},[1449],{"type":30,"value":1196},{"type":25,"tag":331,"props":1451,"children":1452},{"style":1199},[1453],{"type":30,"value":1454},"stringify",{"type":25,"tag":331,"props":1456,"children":1457},{"style":338},[1458],{"type":30,"value":1459},"(archived))\n",{"type":25,"tag":26,"props":1461,"children":1462},{},[1463],{"type":30,"value":1464},"This extracts key fields and adds metadata, making BigQuery queries simpler.",{"type":25,"tag":62,"props":1466,"children":1468},{"id":1467},"query-findings-with-bigquery",[1469],{"type":30,"value":1470},"Query Findings with BigQuery",{"type":25,"tag":26,"props":1472,"children":1473},{},[1474],{"type":30,"value":1475},"Once your findings are in GCS, BigQuery can query them directly:",{"type":25,"tag":74,"props":1477,"children":1481},{"code":1478,"language":1479,"meta":7,"className":1480,"style":7},"-- Create an external table pointing to your GCS bucket\nCREATE EXTERNAL TABLE `project.dataset.guardduty_findings`\nOPTIONS (\n  format = 'JSON',\n  uris = ['gs://guardduty-archive/findings/*']\n);\n\n-- Query high-severity findings from the last 7 days\nSELECT \n  id,\n  type,\n  severity,\n  title,\n  createdAt\nFROM `project.dataset.guardduty_findings`\nWHERE severity >= 7\n  AND DATE(createdAt) >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)\nORDER BY severity DESC;\n","sql","language-sql shiki shiki-themes github-dark",[1482],{"type":25,"tag":79,"props":1483,"children":1484},{"__ignoreMap":7},[1485,1493,1501,1509,1517,1525,1533,1540,1548,1556,1564,1572,1580,1588,1596,1604,1612,1620],{"type":25,"tag":331,"props":1486,"children":1487},{"class":333,"line":334},[1488],{"type":25,"tag":331,"props":1489,"children":1490},{},[1491],{"type":30,"value":1492},"-- Create an external table pointing to your GCS bucket\n",{"type":25,"tag":331,"props":1494,"children":1495},{"class":333,"line":344},[1496],{"type":25,"tag":331,"props":1497,"children":1498},{},[1499],{"type":30,"value":1500},"CREATE EXTERNAL TABLE `project.dataset.guardduty_findings`\n",{"type":25,"tag":331,"props":1502,"children":1503},{"class":333,"line":370},[1504],{"type":25,"tag":331,"props":1505,"children":1506},{},[1507],{"type":30,"value":1508},"OPTIONS (\n",{"type":25,"tag":331,"props":1510,"children":1511},{"class":333,"line":393},[1512],{"type":25,"tag":331,"props":1513,"children":1514},{},[1515],{"type":30,"value":1516},"  format = 'JSON',\n",{"type":25,"tag":331,"props":1518,"children":1519},{"class":333,"line":540},[1520],{"type":25,"tag":331,"props":1521,"children":1522},{},[1523],{"type":30,"value":1524},"  uris = ['gs://guardduty-archive/findings/*']\n",{"type":25,"tag":331,"props":1526,"children":1527},{"class":333,"line":562},[1528],{"type":25,"tag":331,"props":1529,"children":1530},{},[1531],{"type":30,"value":1532},");\n",{"type":25,"tag":331,"props":1534,"children":1535},{"class":333,"line":575},[1536],{"type":25,"tag":331,"props":1537,"children":1538},{"emptyLinePlaceholder":1234},[1539],{"type":30,"value":1237},{"type":25,"tag":331,"props":1541,"children":1542},{"class":333,"line":588},[1543],{"type":25,"tag":331,"props":1544,"children":1545},{},[1546],{"type":30,"value":1547},"-- Query high-severity findings from the last 7 days\n",{"type":25,"tag":331,"props":1549,"children":1550},{"class":333,"line":601},[1551],{"type":25,"tag":331,"props":1552,"children":1553},{},[1554],{"type":30,"value":1555},"SELECT \n",{"type":25,"tag":331,"props":1557,"children":1558},{"class":333,"line":610},[1559],{"type":25,"tag":331,"props":1560,"children":1561},{},[1562],{"type":30,"value":1563},"  id,\n",{"type":25,"tag":331,"props":1565,"children":1566},{"class":333,"line":619},[1567],{"type":25,"tag":331,"props":1568,"children":1569},{},[1570],{"type":30,"value":1571},"  type,\n",{"type":25,"tag":331,"props":1573,"children":1574},{"class":333,"line":637},[1575],{"type":25,"tag":331,"props":1576,"children":1577},{},[1578],{"type":30,"value":1579},"  severity,\n",{"type":25,"tag":331,"props":1581,"children":1582},{"class":333,"line":646},[1583],{"type":25,"tag":331,"props":1584,"children":1585},{},[1586],{"type":30,"value":1587},"  title,\n",{"type":25,"tag":331,"props":1589,"children":1590},{"class":333,"line":655},[1591],{"type":25,"tag":331,"props":1592,"children":1593},{},[1594],{"type":30,"value":1595},"  createdAt\n",{"type":25,"tag":331,"props":1597,"children":1598},{"class":333,"line":1342},[1599],{"type":25,"tag":331,"props":1600,"children":1601},{},[1602],{"type":30,"value":1603},"FROM `project.dataset.guardduty_findings`\n",{"type":25,"tag":331,"props":1605,"children":1606},{"class":333,"line":1351},[1607],{"type":25,"tag":331,"props":1608,"children":1609},{},[1610],{"type":30,"value":1611},"WHERE severity >= 7\n",{"type":25,"tag":331,"props":1613,"children":1614},{"class":333,"line":1360},[1615],{"type":25,"tag":331,"props":1616,"children":1617},{},[1618],{"type":30,"value":1619},"  AND DATE(createdAt) >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)\n",{"type":25,"tag":331,"props":1621,"children":1622},{"class":333,"line":1394},[1623],{"type":25,"tag":331,"props":1624,"children":1625},{},[1626],{"type":30,"value":1627},"ORDER BY severity DESC;\n",{"type":25,"tag":62,"props":1629,"children":1631},{"id":1630},"use-cases",[1632],{"type":30,"value":1633},"Use Cases",{"type":25,"tag":26,"props":1635,"children":1636},{},[1637,1642],{"type":25,"tag":108,"props":1638,"children":1639},{},[1640],{"type":30,"value":1641},"Compliance and audit trails.",{"type":30,"value":1643}," Many compliance frameworks require long-term retention of security events. GCS lifecycle policies can automatically transition old findings to Archive storage.",{"type":25,"tag":26,"props":1645,"children":1646},{},[1647,1652],{"type":25,"tag":108,"props":1648,"children":1649},{},[1650],{"type":30,"value":1651},"Cross-cloud SIEM.",{"type":30,"value":1653}," If you're using Google Chronicle or another GCP-based SIEM, this pipeline feeds findings directly into your security analytics platform.",{"type":25,"tag":26,"props":1655,"children":1656},{},[1657,1662],{"type":25,"tag":108,"props":1658,"children":1659},{},[1660],{"type":30,"value":1661},"Cost optimization.",{"type":30,"value":1663}," AWS GuardDuty retains findings for 90 days. For longer retention, exporting to GCS with lifecycle policies is often cheaper than other archival solutions.",{"type":25,"tag":26,"props":1665,"children":1666},{},[1667,1672],{"type":25,"tag":108,"props":1668,"children":1669},{},[1670],{"type":30,"value":1671},"Multi-cloud correlation.",{"type":30,"value":1673}," Combine GuardDuty findings with security events from GCP and Azure in a single BigQuery dataset for unified threat analysis.",{"type":25,"tag":62,"props":1675,"children":1677},{"id":1676},"conclusion",[1678],{"type":30,"value":1679},"Conclusion",{"type":25,"tag":26,"props":1681,"children":1682},{},[1683],{"type":30,"value":1684},"Routing GuardDuty findings to GCS used to require custom Lambda functions, cross-cloud IAM roles, and ongoing maintenance. With Webhook Relay Service Connections, setup takes minutes:",{"type":25,"tag":172,"props":1686,"children":1687},{},[1688,1693,1698],{"type":25,"tag":104,"props":1689,"children":1690},{},[1691],{"type":30,"value":1692},"Create an SQS queue and EventBridge rule in AWS",{"type":25,"tag":104,"props":1694,"children":1695},{},[1696],{"type":30,"value":1697},"Create a GCS bucket and service account in GCP",{"type":25,"tag":104,"props":1699,"children":1700},{},[1701],{"type":30,"value":1702},"Connect them through Webhook Relay with an SQS input and GCS output",{"type":25,"tag":26,"props":1704,"children":1705},{},[1706],{"type":30,"value":1707},"Your findings are now archived in GCS, ready for BigQuery analysis, Chronicle ingestion, or compliance retention.",{"type":25,"tag":26,"props":1709,"children":1710},{},[1711,1718],{"type":25,"tag":38,"props":1712,"children":1715},{"href":1713,"rel":1714},"https://my.webhookrelay.com/register",[821],[1716],{"type":30,"value":1717},"Sign up for Webhook Relay",{"type":30,"value":1719}," to start archiving GuardDuty findings.",{"type":25,"tag":1721,"props":1722,"children":1723},"style",{},[1724],{"type":30,"value":1725},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":370,"depth":370,"links":1727},[1728,1729,1730,1735,1739,1744,1748,1749,1750,1751],{"id":64,"depth":344,"text":67},{"id":95,"depth":344,"text":98},{"id":147,"depth":344,"text":150,"children":1731},[1732,1733,1734],{"id":154,"depth":370,"text":157},{"id":235,"depth":370,"text":238},{"id":444,"depth":370,"text":447},{"id":683,"depth":344,"text":686,"children":1736},[1737,1738],{"id":702,"depth":370,"text":705},{"id":742,"depth":370,"text":745},{"id":795,"depth":344,"text":798,"children":1740},[1741,1742,1743],{"id":806,"depth":370,"text":809},{"id":875,"depth":370,"text":878},{"id":917,"depth":370,"text":920},{"id":1075,"depth":344,"text":1078,"children":1745},[1746,1747],{"id":1081,"depth":370,"text":1084},{"id":1118,"depth":370,"text":1121},{"id":1142,"depth":344,"text":1145},{"id":1467,"depth":344,"text":1470},{"id":1630,"depth":344,"text":1633},{"id":1676,"depth":344,"text":1679},"markdown","content:blog:guardduty-to-gcs-archival.md","content","blog/guardduty-to-gcs-archival.md","blog/guardduty-to-gcs-archival","md",{"loc":4},[1760,1764,1768,1772,1776,1780,1784,1788,1792,1796,1800,1804,1808,1812,1813,1817,1821,1825,1829,1833,1837,1841,1845,1849,1852,1856,1860,1864,1868,1872,1876,1880,1884,1888,1892,1895,1899,1903,1907,1911,1914,1918,1922,1926,1930,1934,1938,1942,1946,1950],{"_path":1761,"title":1762,"description":1763},"/blog/airtable-integrations","Airtable integrations: inserting rows","How to setup Airtable  on setting up HTML contact form with Airtable code webhook integration",{"_path":1765,"title":1766,"description":1767},"/blog/auto-deploy-on-git-push","Auto deploy your Node.js app on push to GitHub","Learn how to update your Node.js app on push to GitHub using webhooks on any virtual machine or your local computer",{"_path":1769,"title":1770,"description":1771},"/blog/auto-transform-webhook","Automatically transform webhook payloads","Automatically transform webhook payloads using AI in Webhook Relay. Step-by-step guide to convert webhook data between different formats without coding.",{"_path":1773,"title":1774,"description":1775},"/blog/automated-github-pull-request-builds-on-jenkins","Automated Jenkins builds on GitHub pull request","Configuration example on how to automatically start builds on GitHub pull request",{"_path":1777,"title":1778,"description":1779},"/blog/azure-functions-vs-webhook-relay","Azure Functions vs Webhook Relay: Why I stopped overengineering webhooks","A practical comparison of Azure Functions and Webhook Relay for webhook processing, with code examples showing the difference in setup complexity.",{"_path":1781,"title":1782,"description":1783},"/blog/cdn-types-and-setup","CDN types and setting them up (Vue, React)","CDN (content delivery network) types and how to set one up (Vue, React)",{"_path":1785,"title":1786,"description":1787},"/blog/cloudflare-support-for-home-assistant","Introducing Cloudflare support for Home Assistant remote access","Webhook Relay Home Assistant remote access add-on now support Cloudflare Domains",{"_path":1789,"title":1790,"description":1791},"/blog/docker-compose-update-on-github-webhooks","Docker Compose update on Github webhook","Learn how to update Docker Compose on push to Github using webhooks",{"_path":1793,"title":1794,"description":1795},"/blog/domain-based-webhook-endpoints","New feature announcement: domain-based endpoints","Introducing new feature: domain based webhook endpoints",{"_path":1797,"title":1798,"description":1799},"/blog/dotscience-tunnels-jupyter","How Dotscience manages thousands of tunnels to create a better Data Science environment","A case study on how Dotscience utilizes Webhook Relay tunnels",{"_path":1801,"title":1802,"description":1803},"/blog/extra-webhook-packages","Introducing extra webhook packages","Purchase additional webhook capacity directly from your current plan tier",{"_path":1805,"title":1806,"description":1807},"/blog/github-jenkins-guide","Receive Github webhooks on Jenkins without public IP","A short tutorial on how to configure and receive Github webhooks on your jenkins instance even without a public IP",{"_path":1809,"title":1810,"description":1811},"/blog/google-home-ifttt-node-red","Controlling TV with Google Home, IFTTT and Node-RED","Easiest way to start controlling your TV with Google Home, IFTTT and Node-RED",{"_path":4,"title":8,"description":9},{"_path":1814,"title":1815,"description":1816},"/blog/hassio-tls-tunnels-duckdns","Home Assistant remote access add-on","Reverse tunnels for testing and development environments",{"_path":1818,"title":1819,"description":1820},"/blog/home-assistant-remote-access","Hassle-free remote access to Home Assistant on a Raspberry Pi","How to connect to your Home Assistant without public IP or NAT configuration",{"_path":1822,"title":1823,"description":1824},"/blog/how-to-create-webhook","What is a webhook and how to create one?","Webhooks are key to building reliable and responsive systems. However, you must know how to use them properly. Let's explore what is a webhook and how to support webhooks in your application",{"_path":1826,"title":1827,"description":1828},"/blog/ingesting-facebook-webhooks","Ingesting Facebook webhooks (challenge & verification)","How to receive Facebook webhooks and do verification for challenge and token",{"_path":1830,"title":1831,"description":1832},"/blog/ingress-with-docker-for-mac","Web Relay Ingress with Docker for Mac","Web Relay ingress for Mac lets users expose their local services to the internet for testing and demoing",{"_path":1834,"title":1835,"description":1836},"/blog/install-jenkins-ci-docker","How to install and run a dockerized Jenkins CI with webhook support","A quick tutorial on how to setup a Jenkins CI server using Docker, Synpse and Webhook Relay to have remote SSH access and secure webhooks",{"_path":1838,"title":1839,"description":1840},"/blog/introducing_service_connections","Introducing Service Connections","Connect AWS, GCP, and Azure services through Webhook Relay buckets with fast, flexible cloud-to-cloud routing.",{"_path":1842,"title":1843,"description":1844},"/blog/introducing-keel","Keel - automated Kubernetes updates","Automatically update kubernetes deployments on image push",{"_path":1846,"title":1847,"description":1848},"/blog/introducing-websocket-server","Introducing WebSocket Server","Listen for new webhooks directly from your application using websockets",{"_path":1850,"title":1851,"description":1816},"/blog/introduction","Introduction to Webhook Relay",{"_path":1853,"title":1854,"description":1855},"/blog/kubernetes-redis-commander","DevOps Use Case: Performing Redis maintenance in Kubernetes","Use Redis-Commander with Webhook Relay ingress controller to access Redis in a Kubernetes cluster",{"_path":1857,"title":1858,"description":1859},"/blog/lightning-ai-company-webhooks-setup","How Lightning AI uses WHR to ship webhooks to the entire team","How Lightning AI uses Webhook Relay container to broadcast Stripe webhooks to every developer's laptop and staging environment simultaneously - zero setup required",{"_path":1861,"title":1862,"description":1863},"/blog/mailgun-webhook-fanout","Mailgun webhook fan-out","How to send mailgun webhooks to multiple destinations",{"_path":1865,"title":1866,"description":1867},"/blog/may-10th-outage-gke-controlplane","Managed GKE control-plane failure resulting in platform outage on 10th May, 2022","An RCA on how the managed GKE control-plane failure brought down the platform",{"_path":1869,"title":1870,"description":1871},"/blog/nodered-owntracks-direct","Node-RED OwnTracks location tracking without public IP/MQTT","How to get webhooks from OwnTracks to Node-RED without public IP or configuring NAT",{"_path":1873,"title":1874,"description":1875},"/blog/openapi-redoc-tutorial","Documenting your API with OpenAPI (Swagger) and Redoc","API tooling review and a guide on how to document your API with Swagger's OpenAPI and Redoc",{"_path":1877,"title":1878,"description":1879},"/blog/pricing-changes","Changes to our prices for new customers","As of 1st of May 2021, new WHR subscribers will be subject to new prices.",{"_path":1881,"title":1882,"description":1883},"/blog/rancher-push-to-deploy-workflow","Rancher - push to deploy workflow with Keel","Configuring push to deploy workflow with Rancher and Keel",{"_path":1885,"title":1886,"description":1887},"/blog/receiving-paypal-webhooks-localhost","How to receive Paypal webhooks on localhost","Often when building an application that integrates with 3rd party services we need a way to receive webhooks",{"_path":1889,"title":1890,"description":1891},"/blog/receiving-shopify-webhooks-flask-api","Receive Shopify webhooks on Flask API","How to get Shopify webhooks working on your local Flask app, with proper signature verification",{"_path":1893,"title":1894,"description":1887},"/blog/receiving-stripe-webhooks-localhost","How to receive Stripe webhooks on localhost",{"_path":1896,"title":1897,"description":1898},"/blog/remote-tube-downloader","Remote YouTube downloader Slack bot","A short tutorial to help you build a remote YouTube video downloader using WebSockets and Slack",{"_path":1900,"title":1901,"description":1902},"/blog/responding-to-api-calls-on-nodered","Responding to API calls using Node-RED Webhook Relay node","How to respond to API calls using Node-RED Webhook Relay node",{"_path":1904,"title":1905,"description":1906},"/blog/setting-up-selfhosted-metabase","Self-hosted business intelligence with Metabase","Setting up self-hosted Metabase on-prem",{"_path":1908,"title":1909,"description":1910},"/blog/static-ip","Static IPs for outgoing webhooks","How to setup static IPs for webhook calls to enable whitelisting",{"_path":1912,"title":1913,"description":1910},"/blog/static-ips-for-webhook-whitelisting","Static IPs for webhook calls to enable whitelisting",{"_path":1915,"title":1916,"description":1917},"/blog/stripe-webhook-to-email","Receive emails on new Stripe subscribers","It's nice to get Stripe notifications on new payments however we can turn any Stripe into an email",{"_path":1919,"title":1920,"description":1921},"/blog/trading-view","TradingView webhooks","Learn how to integrate TradingView with Discord to automate trading alerts. Step-by-step guide for connecting TradingView alerts to your preferred destinations.",{"_path":1923,"title":1924,"description":1925},"/blog/tunnels-to-kubernetes","Providing access to Kubernetes through tunnels in one of the largest cities in Lithuania","How Lithuania's transport operator uses Webhook Relay tunnels to provide easy access to private Kubernetes clusters using TLS pass-through tunnels mixed with an ingress",{"_path":1927,"title":1928,"description":1929},"/blog/using-drone-for-simple-selfhosted-ci-cd","Setting up simple, self-hosted & fast CI/CD solution with Drone.io","A guide/tutorial on how to set up Drone as a self-hosted CI/CD solution for private projects",{"_path":1931,"title":1932,"description":1933},"/blog/using-google-firestore-for-go-backend","Using Google Firestore for a Golang backend application","Switching from internal KV store to a Google Firestore can be quick and easy",{"_path":1935,"title":1936,"description":1937},"/blog/webhook-rule-based-filters","Rules-based webhook filtering & routing","Example use-case of rules-based routing and filtering for GitHub webhooks",{"_path":1939,"title":1940,"description":1941},"/blog/webhook-security","Webhook Security: Best Practices to Secure Your Webhooks","Explore essential measures to fortify your webhooks. Dive into the latest security best practices to ensure reliable, safe data transfers and protect your applications from vulnerabilities.",{"_path":1943,"title":1944,"description":1945},"/blog/webhookrelayd-with-podman","Running Webhook Relay agent with Podman","A short guide how to run Webhook Relay agent with Podman",{"_path":1947,"title":1948,"description":1949},"/blog/webhooks-to-jenkins-on-kubernetes","Secure webhooks to Jenkins on Kubernetes","A tutorial on how to securely receive GitHub webhooks on your Jenkins inside a Kubernetes cluster",{"_path":1951,"title":1952,"description":1953},"/blog/what-is-webhook","What is a webhook and how to use them?","What are webhooks and where they are usually used. An example application that receives a webhook and best practices when dealing with webhooks.",[1955,1959,1963,1967,1971,1975,1979,1983,1987,1991,1995,1999,2003,2007,2011,2013,2017,2021,2024,2027,2031,2035,2039,2043,2047,2051,2055,2059,2063,2067,2071,2075,2079,2083,2087,2091,2095,2099,2103,2107,2111,2115,2119,2123,2127,2131,2135,2139,2143,2147,2151,2155,2159,2162,2166,2169,2173,2177,2180,2184],{"_path":1956,"title":1957,"description":1958},"/docs/account/account-management","Account management","How to manage your account, change email address, password or delete your account",{"_path":1960,"title":1961,"description":1962},"/docs/account/team","Teams and sub-accounts","How to create teams and invite team members to your Webhook Relay account",{"_path":1964,"title":1965,"description":1966},"/docs/account/billing-and-subscriptions","Billing & subscriptions","How to manage your billing and subscriptions, updating payment methods and billing address, viewing invoices",{"_path":1968,"title":1969,"description":1970},"/docs","Getting Started","What is Webhook Relay and how you can use it.",{"_path":1972,"title":1973,"description":1974},"/docs/installation/cli","CLI","Learn how to install relay CLI on MacOS, Linux and Windows to start forwarding webhooks to your internal services and open tunnels to expose your services",{"_path":1976,"title":1977,"description":1978},"/docs/installation/docker","Docker container","How to use Webhook Relay client with Docker to start forwarding webhooks to your internal services and open tunnels to expose your services",{"_path":1980,"title":1981,"description":1982},"/docs/installation/docker-compose","Docker Compose","How to use Webhook Relay client with Docker Compose to start forwarding webhooks to your internal services and open tunnels to expose your services",{"_path":1984,"title":1985,"description":1986},"/docs/installation/kubernetes","Kubernetes","How to use Webhook Relay client with Kubernetes to start forwarding webhooks to your internal services and open tunnels to expose your services",{"_path":1988,"title":1989,"description":1990},"/docs/installation/autostart-windows","Autostart (Windows)","Learn how to configure background service so that Webhook Relay agent connects on Windows server startup",{"_path":1992,"title":1993,"description":1994},"/docs/installation/autostart-linux","Autostart (Linux)","Learn how to configure background service so that Webhook Relay agent connects on Linux server startup",{"_path":1996,"title":1997,"description":1998},"/docs/installation/autostart-macos","Autostart (MacOS)","Learn how to configure background service so that Webhook Relay agent connects on MacOS startup",{"_path":2000,"title":2001,"description":2002},"/docs/installation/behind-proxy","HTTP proxy configuration","How to configure relay or webhookrelayd agent to work behind a proxy",{"_path":2004,"title":2005,"description":2006},"/docs/mcp","MCP Server","Use the Webhook Relay MCP server to manage buckets, webhook logs, transform functions, and cloud service connections from AI agents.",{"_path":2008,"title":2009,"description":2010},"/docs/security","Security & Tech","We will address the most common questions about the system, protocols involved, and security policies.",{"_path":40,"title":43,"description":2012},"Connect Webhook Relay to AWS and GCP cloud services. Receive events from S3, SQS, SNS, GCS, Pub/Sub and send webhooks to cloud providers.",{"_path":2014,"title":2015,"description":2016},"/docs/service-connections/aws_s3","AWS S3","Receive S3 object notifications as webhooks and upload webhook data to S3 buckets using Webhook Relay service connections.",{"_path":2018,"title":2019,"description":2020},"/docs/service-connections/aws_sns","AWS SNS","Subscribe to Amazon SNS topics and publish webhook data to SNS using Webhook Relay service connections.",{"_path":165,"title":2022,"description":2023},"AWS SQS","Poll messages from Amazon SQS queues and send webhook data to SQS using Webhook Relay service connections.",{"_path":694,"title":2025,"description":2026},"GCP Cloud Storage","Receive GCS object notifications as webhooks and upload webhook data to Google Cloud Storage using Webhook Relay service connections.",{"_path":2028,"title":2029,"description":2030},"/docs/service-connections/gcp_pubsub","GCP Pub/Sub","Subscribe to Google Cloud Pub/Sub topics and publish webhook data to Pub/Sub using Webhook Relay service connections.",{"_path":2032,"title":2033,"description":2034},"/docs/tunnels/demoing-your-website","Demoing your website","How to expose your local web server to the internet without public IP or router changes",{"_path":2036,"title":2037,"description":2038},"/docs/tunnels/regions","Regions","Regional tunnel servers are available in a number of different locations to enable fast & low latency traffic to your applications.",{"_path":2040,"title":2041,"description":2042},"/docs/tutorials/cicd/jenkins-bitbucket","Jenkins and Bitbucket","A quick guide on Jenkins Bitbucket webhooks integration without public IP/NAT or behind a firewall",{"_path":2044,"title":2045,"description":2046},"/docs/tutorials/cicd/jenkins-github","Jenkins and GitHub","Configuring Jenkins CI to receive webhooks from Github without public IP/NAT or behind a firewall",{"_path":2048,"title":2049,"description":2050},"/docs/tutorials/cicd/kubernetes-operator","Kubernetes Operator","Trigger Jenkins builds on push to Github using Webhook Relay Operator",{"_path":2052,"title":2053,"description":2054},"/docs/tutorials/cicd/terraform-atlantis","Terraform Atlantis","Securely forward webhooks to Terraform Atlantis in Kubernetes cluster using Webhook Relay Operator",{"_path":2056,"title":2057,"description":2058},"/docs/tutorials/cicd/webhook-exec","Execute scripts on webhook","Execute commands such as bash, python or ruby when webhooks are received",{"_path":2060,"title":2061,"description":2062},"/docs/tutorials/edge/home-assistant","Home Assistant","Connecting to your Home Assistant remotely without domain/public IP or configuring NAT.",{"_path":2064,"title":2065,"description":2066},"/docs/tutorials/edge/javascript-app","JavaScript app","Receive webhooks directly inside your application without public IP",{"_path":2068,"title":2069,"description":2070},"/docs/tutorials/edge/node-red","Node-RED","Directly receiving and process webhooks in Node-RED instance without public IP or domain.",{"_path":2072,"title":2073,"description":2074},"/docs/tutorials","Tutorials","Tutorials for Webhook Relay.",{"_path":2076,"title":2077,"description":2078},"/docs/tutorials/transform/docker-to-slack","DockerHub webhook to Slack notification","Use Lua function to convert DockerHub webhook request to Slack channel notification",{"_path":2080,"title":2081,"description":2082},"/docs/tutorials/transform/enrich-webhooks","Enrich webhooks from APIs","Call 3rd party API and transform your webhook before sending it to the final destination",{"_path":2084,"title":2085,"description":2086},"/docs/tutorials/warehouse/bigquery","GCP BigQuery","Learn to insert and stream data into BigQuery from webhooks",{"_path":2088,"title":2089,"description":2090},"/docs/webhooks/auth/username-password","Username and password","How to set up authentication for webhooks. This guide shows you how to use basic username and password or token authentication.",{"_path":2092,"title":2093,"description":2094},"/docs/webhooks/auth/hmac","HMAC","HMAC is the most popular authentication and message security method used on webhook requests. Learn how to validate HMAC signatures",{"_path":2096,"title":2097,"description":2098},"/docs/webhooks/auth/jwt","JWT authentication","a helper JWT package is available to validate and authenticate webhooks",{"_path":2100,"title":2101,"description":2102},"/docs/webhooks/auth/http-method","Auth using request method","How do I allow only POST requests through the input or output?",{"_path":2104,"title":2105,"description":2106},"/docs/webhooks/cors","CORS for webhooks","Configure CORS for your webhooks to allow requests from other domains.",{"_path":2108,"title":2109,"description":2110},"/docs/webhooks/cron/using-cron-webhooks","Schedule recurring webhooks","Schedule recurring webhooks with Webhook Relay",{"_path":2112,"title":2113,"description":2114},"/docs/webhooks/custom-domains","Custom webhook domains","Receive, process and forward webhooks using your own domain name.",{"_path":2116,"title":2117,"description":2118},"/docs/webhooks/custom-subdomains","Custom webhook subdomains","Receive, process and forward webhooks using webhookrelay.com subdomain.",{"_path":2120,"title":2121,"description":2122},"/docs/webhooks/custom-webhook-response","Custom response to webhooks","Configure a custom response to your webhooks, some applications require it, for example Facebook webhooks.",{"_path":2124,"title":2125,"description":2126},"/docs/webhooks/functions/manipulating-json","JSON encoding","How to encode and decode JSON in Webhook Relay Functions",{"_path":2128,"title":2129,"description":2130},"/docs/webhooks/functions/make-http-request","Make HTTP request","Making HTTP requests from Webhook Relay Functions",{"_path":2132,"title":2133,"description":2134},"/docs/webhooks/functions/modify-request","Read, write request data","How to access and modify request data in Webhook Relay Functions",{"_path":2136,"title":2137,"description":2138},"/docs/webhooks/functions/multipart-form-data","Multipart form to JSON","Parsing multipart form data inside the Webhook Relay Function",{"_path":2140,"title":2141,"description":2142},"/docs/webhooks/functions/url-encoded-data","URL Encoded Form","Parse and convert URL encoded form data into JSON or any other format",{"_path":2144,"title":2145,"description":2146},"/docs/webhooks/functions/working-with-time","Working with time","Webhook Relay provides several helpers when working with time, this section shows how to get current time, how to parse and format time",{"_path":2148,"title":2149,"description":2150},"/docs/webhooks/functions/send-emails","Sending emails","Webhook Relay provides a Mailgun package to easily send emails on various events.",{"_path":2152,"title":2153,"description":2154},"/docs/webhooks/functions/crypto-functions","Base64, encryption","How to generate hmac, crc32, sha1, sha256, sha512 hashes and encrypt data in Webhook Relay functions",{"_path":2156,"title":2157,"description":2158},"/docs/webhooks/functions/integrate-into-cicd","Integrating into CI/CD","A guide on how to automatically deploy Functions in various source control management systems",{"_path":2160,"title":2085,"description":2161},"/docs/webhooks/functions/big-query","How to send data to BigQuery from Webhook Relay.",{"_path":2163,"title":2164,"description":2165},"/docs/webhooks/functions/accessing-metadata","Accessing metadata","Accessing metadata from Webhook Relay Functions",{"_path":1153,"title":2167,"description":2168},"Functions","Use functions to transform webhooks, modify payloads, filter requests, integrate systems, and more.",{"_path":2170,"title":2171,"description":2172},"/docs/webhooks/internal/localhost","Receiving webhooks on localhost","Receive webhooks on localhost or private networks with Webhook Relay forward command",{"_path":2174,"title":2175,"description":2176},"/docs/webhooks/public/public-destination","Forward to public URL","How to forward a webhook to a single public URL",{"_path":2178,"title":2179,"description":2176},"/docs/webhooks/public/multiple-destination-urls","Multiple destinations",{"_path":2181,"title":2182,"description":2183},"/docs/webhooks/static-ip-address","Static IP Address","Enable a static IP address for outgoing webhooks to allow IP whitelisting.",{"_path":2185,"title":2186,"description":2187},"/docs/webhooks/websocket-server","Connecting to websocket server","Webhook Relay websocket server allows your applications to directly process webhooks without having a public IP.",[2189,2192,2196,2200,2204,2208,2212,2216,2219,2222,2226,2230,2234,2238],{"_path":2190,"title":2191,"description":7},"/features/audit-logs","Audit Logs",{"_path":2193,"title":2194,"description":2195},"/features/custom-domains","Custom Domains","How to use custom domains for your webhook endpoints",{"_path":2197,"title":2198,"description":2199},"/features/custom-subdomains","Custom Subdomains","How to use custom subdomains for your webhook endpoints",{"_path":2201,"title":2202,"description":2203},"/features/forwarding-rules","Forwarding Rules - Filter and Route Webhooks","Filter and route webhooks based on request body, JSON paths, URL query parameters, URL path, and IP address. Precisely control which webhooks reach each destination.",{"_path":2205,"title":2206,"description":2207},"/features/rewrite-host-header","Rewriting Host Header","How to rewrite the Host header to enable exposing local servers to the internet",{"_path":2209,"title":2210,"description":2211},"/features/sso","Single Sign-On (SSO)","How to enable single sign-on for your Webhook Relay account so it can be shared with your organization",{"_path":2213,"title":2214,"description":2215},"/features/static-outgoing-ip","Static Outgoing IP Address","How to use a static outgoing IP address for your webhooks to unlock integrations that require whitelisting your IP address",{"_path":2217,"title":2218,"description":7},"/features/team-member-roles","Team Member Roles",{"_path":2220,"title":2221,"description":1962},"/features/teams","Teams",{"_path":2223,"title":2224,"description":2225},"/features/transform-webhooks","Serverless Webhook Transformations","How to transform webhooks before forwarding them to your destination",{"_path":2227,"title":2228,"description":2229},"/features/transform-webhooks-with-ai","Transform Webhooks with AI","How to automatically transform webhook payloads using AI for seamless integrations",{"_path":2231,"title":2232,"description":2233},"/features/webhook-kubernetes-integration","Webhook Relay Kubernetes Integration","Seamlessly connect your Kubernetes services to external webhooks without exposing them directly to the internet using the Webhook Relay Operator.",{"_path":2235,"title":2236,"description":2237},"/features/webhook-multiple-destinations","Forward Webhooks to Multiple Destinations","Webhook Relay allows you to forward webhooks to multiple destinations. Ideal for data replication and backup.",{"_path":2239,"title":2240,"description":2241},"/features/webhook-to-internal-server","Webhooks to Internal Servers","Webhook Relay allows you to forward webhooks to internal servers",1773247654933]