Support casework

Support casework.

Three documented problems, shown from report through resolution. Each case names where the evidence came from and what it can actually prove.

At a glance

On this page

Case 1 / End-user investigation

Android device investigation

Context and provenance
A member's Android phone, described and documented in a published personal investigation. Not a customer device or a work assignment.
Reported or observable problem
The phone was showing unexpected pop-ups and faster-than-normal battery drain. The member could not say when it started or what they had installed.
User or operator impact
A non-technical user was uncomfortable using their own phone and could not tell what was safe to keep or remove.
Initial questions
What had changed recently. Whether any app was installed outside the Play Store. Whether the behavior was constant or triggered by specific actions.
Investigation
I isolated the device from other networks first, then used ADB to list installed packages and compared install timestamps against when the symptoms began, narrowing the search to one package.
Finding
The identified package matched known adware behavior. I reverse-engineered the APK with APKTool and JADX to see what it was actually doing, then correlated its indicators through VirusTotal and open-source research.
Resolution
Confirmed the package as the source, removed it, and explained in plain language what it had been doing and why it was unsafe to keep.
Prevention and documentation
Documented the investigation, including the identification method and the indicators found, in a published writeup. Identifiers and the sample itself stayed redacted.
Customer-facing explanation
"This app was reading more than it needed to and showing you ads based on that. I removed it and confirmed nothing else on your phone matches the same pattern."
Engineering handoff
Package name and install timestamp, ADB output, APKTool and JADX findings, and VirusTotal and OSINT correlation. Indicators and the sample were redacted for publication.
Boundary
This was a single consumer device investigated after the fact, not a live incident response engagement with logging or EDR already in place.

Source: the original writeup on Medium (opens in a new tab).

Case 2 / Personal integration case

Silent API write

Context and provenance
Personal project, verified against a live Wazuh manager as part of the Detection-as-Code Pipeline's deploy tooling. Not a customer ticket or a production incident.
Reported or observable problem
A PUT to update a rule file returned HTTP 200, the normal success code, but the file on the manager had not actually changed.
User or operator impact
Anyone trusting the status code alone would believe a rule update had deployed when it had not, leaving a stale detection rule in place.
Initial questions
Whether the request was reaching the manager at all. Whether the response body carried more information than the status code. Whether the condition was consistent or intermittent.
Investigation
I reproduced the call directly against the manager. The status code stayed 200 every time, but the response body reported error: 1, and the file content had not changed.
Finding
The write silently failed whenever the target filename already existed and the request omitted overwrite=true. The API accepted the request and returned success at the transport layer while rejecting it at the application layer.
Resolution
Added the explicit overwrite=true parameter, then added a post-write check that inspects the body-level error and total_failed_items fields rather than trusting the status code alone.
Prevention and documentation
Added a regression test that exercises this exact condition, documented it, and set deploy tooling to abort the rest of a reconciliation run on any body-level failure.
Customer-facing explanation
"I reproduced the issue. The request is completing at the HTTP layer, but the remote file is not changing. I am checking the response body and current state rather than repeating the same write. My next update will include either a verified change or the exact failure conditions needed for escalation."
Engineering handoff
Endpoint: PUT rule file, existing filename. Expected state: file updated, body reports success. Observed state: HTTP 200, body error: 1, file unchanged. Reproduction condition: overwrite=true omitted. Regression action: test added, deploy aborts on body-level failure.
Boundary
This is one deployment API's behavior in one project, not a general claim about REST API design. The regression test covers this specific condition, not the full space of partial-failure responses.

Source: Detection-as-Code Pipeline, threat model and deploy-rule test suite.

Case 3 / Personal systems case

Self-hosted access stack

Context and provenance
A self-hosted identity and deception lab I built and operate on my own hardware, a macOS host with a Linux virtual machine. Personal systems work, not a client environment.
Reported or observable problem
Container startup failures. The identity service and its database entered a permission loop under a mounted host volume, and one component had no published image for the machine's ARM64 architecture at all.
User or operator impact
As the only operator, any of these failures took the whole stack down until I fixed it. There was no one else to escalate to.
Initial questions
Whether the failure was the container image, the volume mount, or the host filesystem. Whether it was architecture-specific. Whether a dependency's expected input format had changed.
Investigation
I traced the permission loop to how the container image's user mapped onto a VirtioFS-backed host volume mount, and confirmed the missing image was an architecture gap by checking the registry directly for an AArch64 build.
Finding
Three separate root causes. Ownership mismatches between the container user and the mounted volume, no published AArch64 image for one component, and a cryptography library enforcing exact base64 padding and key-length constraints I had not matched.
Resolution
Adjusted volume ownership and mount handling, compiled the missing component natively for AArch64, corrected the key material to the exact length and padding the library expected, and reassigned colliding ports so every service could bind.
Prevention and documentation
Wrote setup and operating documentation covering each of these fixes so the stack rebuilds cleanly on either machine without re-diagnosing the same issues.
Customer-facing explanation
"The service wasn't starting because of how the container's file permissions and the host machine disagreed, not because of anything wrong with the data itself. I fixed the permission mapping and it starts clean now."
Engineering handoff
Alpine container UID or GID mismatch against a VirtioFS-backed bind mount. Missing arm64 image for one component, resolved with a native build. PyNaCl key-length and base64 padding mismatch at initialization. Two services requesting the same host port.
Boundary
This is a single self-hosted lab on personal hardware, not an enterprise identity platform or a production SSO deployment at any scale.

Source: Deceptive Identity Architecture project page.

Workflow lab

How I modeled a support workflow.

Scope Synthetic workflow lab, not a production ITSM deployment. Every user, device, alert, ticket, and approval in it is fictional.

I built Control Plane to work through the chain a support request actually travels, from the person reporting it to the evidence that closes it out, using open tooling rather than a commercial ITSM platform.

  1. Request Intake A request enters the system and gets a record.
  2. Identity Identity lookup The requester is resolved against a directory with roles and groups.
  3. MFA Multi-factor check Sensitive actions require a verified MFA enrollment, modeled with Keycloak TOTP.
  4. Endpoint state Device posture The requesting device's known state is checked before anything proceeds.
  5. Ticket Ticket and SLA The request becomes a tracked ticket against a service level.
  6. Approval Separation of duties A change requires approval from someone other than its requester. Self-approval is denied.
  7. Action Containment or change The approved action executes, such as an isolation or a remediation step.
  8. Evidence Closure evidence The case closes only against evidence in a hash-chained, append-only ledger.

Concepts modeled: joiner, mover, and leaver identity changes; ticket workflow and service levels; approval and separation of duties; change management; a knowledge base; device posture; and documented closure evidence. Source: Control Plane project page.

Workflow lab

How I modeled a diagnosis that has to prove itself.

Scope Synthetic SAML corpus against a self-hosted Keycloak identity provider, not a production IdP. Customer narratives are authored text standing in for real tickets, not real conversations.

A ticket that says sign-in is broken can have close to a dozen distinct causes that look identical from the person's chair, an expired certificate, a mismatched audience value, a stale attribute mapping. I built Assertion Desk to work through that ambiguity in order, and to make sure the answer handed back names the specific check that failed instead of a guess dressed up as confidence.

  1. Intake Custody and quarantine Artifacts are scanned for secret patterns before anything else touches them.
  2. Verify Deterministic checks Signature, audience, NameID, conditions, and clock skew are checked against the actual assertion.
  3. Extract Read the report The customer's own description is turned into structured facts: onset, recent change, what they believe is wrong.
  4. Draft Draft the explanation A summary and a root-cause explanation are drafted, grounded only in what the checks found.
  5. Gate Verify the explanation itself Every claim in the draft is checked against a verified finding, and a claim that points at a gap gets rejected.
  6. Decide Case disposition The outcome is computed from the checks and the grounding verdict, never from parsed model text.
  7. Approve Human review A person reviews the grounded draft and its evidence before anything is marked ready.
  8. Close Publish with evidence What ships names the specific check that failed and the artifact that proved it, not just that the case is resolved.

Concepts modeled: evidence custody ahead of investigation; deterministic checks ahead of generated explanations; a validator that rejects an unsupported claim before a human sees it; and closure evidence over a closure claim. Source: Assertion Desk project page.