FN/04 · HIPAA · CI/CD · AUDIT

The HIPAA CI/CD audit checklist for engineering teams.

The practitioner's control map we use during 2-week audit engagements, with the CFR section, the auditor's question, and the architectural fix for each one.

A HIPAA CI/CD audit is not a paperwork exercise. The auditor will examine the pipeline and ask specific questions, and the architecture has to be able to answer them in seconds, not weeks.

A healthcare engineering team called me four weeks before their first 3PAO assessment. They had a CI/CD pipeline that shipped well. They had no idea whether it would survive scrutiny. Their compliance officer had sent them a checklist. Their auditor had sent a different checklist. The procurement reviewer at their largest customer had sent a third. None of the three agreed on what specifically the auditor would examine in the pipeline itself.

We pulled the latest production deploy log together. The pipeline ran. The deploy succeeded. But the deploy authorization was attributable to a CI service account, not a human. The signed artifact lived in a registry the engineering team could write to. The scanner results were stored as pipeline run artifacts that expired after 90 days. The HIPAA Security Rule asks for audit controls (§ 164.312(b)), integrity controls (§ 164.312(c)(1)), and access management (§ 164.308(a)(4)). The pipeline could not answer any of them.

The fix was architectural, not procedural. Over six weeks we rebuilt the pipeline so the auditor's questions could be answered in seconds. Signed artifacts with retention-locked evidence. Identity-attributable deploys. Continuous scanning with policy gates. Evidence stored separately from CI infrastructure. The assessment cleared on first-party review.

That engagement is also where this checklist comes from. It is the same control map we use during 2-week HIPAA CI/CD audits at Stonebridge, organized in the order I would actually walk a pipeline through it. Each control maps to a specific CFR section, the auditor's actual question, what passes, what fails, and the architectural fix. Use this before an audit. Use it during scoping when you do not know whether you have a problem. Use it as the basis for the remediation roadmap your compliance officer asks for.

01 — ScopeWhat this checklist is, and what it is not.

This checklist covers the technical safeguards of the HIPAA Security Rule (45 CFR Part 164 Subpart C) as they apply specifically to the build, test, and deploy pipeline. The scope is the pipeline itself: source repositories, CI runners, registries, signing infrastructure, deployment targets, and the evidence the pipeline produces along the way.

It does not cover Business Associate Agreement management. It does not cover PHI access controls inside the running application. It does not cover workforce training, sanction policy, or the administrative safeguards required by § 164.308(a)(1) and § 164.308(a)(5). Those are real obligations, but they are not what your auditor will examine when they ask to see the pipeline.

It is also not a substitute for a real audit. A 2-week Stonebridge engagement produces a written control mapping, a prioritized remediation roadmap, and effort estimates. This checklist gets you to the point where you know what the engagement would surface. For deeper architectural context on the patterns referenced below, the HIPAA CI/CD implementation guide covers the parent/child pipeline architecture, isolated runners, and policy gates that satisfy most of these controls structurally.

02 — How to use itPull evidence first. Then walk the controls.

The most common mistake teams make before a HIPAA CI/CD audit is trying to fix gaps before they know what the gaps are. I have watched engineering teams spend two weeks rebuilding their signing chain only to discover their bigger exposure was a logging account with read-only access for the wrong people.

Run the checklist in this order. Spend the first two hours pulling evidence onto a single shared document, then walk the controls with the evidence visible. Each control either has supporting evidence or it does not; trying to remember from memory whether something is configured correctly is how teams sign off on findings that fail under scrutiny.

The evidence pull at minimum:

  • Pipeline configuration files for every active branch (the entire .gitlab-ci.yml or .github/workflows/ tree)
  • The latest 30 days of pipeline run logs for production deploys
  • The most recent scanner outputs (SAST, SCA, container CVE, IaC, secrets) for the production branch
  • The signing chain: signing keys, key rotation history, signature verification logs
  • The current contents of the evidence bucket, including retention configuration
  • The IAM, RBAC, or equivalent identity grants for every account or principal that can deploy to a PHI-bearing environment
  • The CloudTrail, audit log, or equivalent showing the last 90 days of admin actions on production

With that on the table, the rest of the checklist becomes a query, not a memory test. The patterns below are organized by control family, not in the order the Security Rule presents them, because the practitioner walk is faster when you group by where the evidence lives. The architecture pattern we use emits this evidence as a property of how the pipeline runs, so the pull becomes a one-line query instead of a forensic exercise.

03 — Identity and accessWho can deploy to PHI-bearing environments.

This is the first thing auditors actually look at, and it is the most commonly broken in pipelines designed without compliance posture in mind. The relevant Security Rule sections are § 164.308(a)(3) (workforce security), § 164.308(a)(4) (information access management), and § 164.312(a)(1) (access control). All three reduce to the same engineering question: who, by named identity, can change production state.

§ 164.308(a)(4) · Information access management

Deploy authorization is attributable to a named human identity.

"Show me, by named identity, every human who has deployed to production in the last 90 days."

Passes
Federated identity from corporate IdP (Okta, Entra ID, IAM Identity Center) to CI. Every deploy runs under a role assumed by a named human via SSO with phishing-resistant MFA. The deploy event log shows the human, the timestamp, and the role assumed.
Fails
Long-lived CI service account credentials. Shared "deploy" tokens passed in environment variables. Deploy keys checked into a vault any developer can read. "The pipeline did it" is not a name.
Fix
OIDC federation between CI and cloud (GitHub OIDC to AWS, Workload Identity Federation for GCP). Short-lived role assumption per pipeline run. Named-human approval required at the production gate, recorded with identity and timestamp.
§ 164.308(a)(3) · Workforce security

Access grants and revocations are auditable and time-bounded.

"Show me when this developer was granted production access and when it was revoked."

Passes
Access is granted through the IdP with a documented approval workflow. Time-bounded role assumption (hours, not days). Quarterly access reviews logged. Revocation propagates from IdP through CI within minutes.
Fails
Permissions held directly in CI (GitHub repo collaborator, GitLab project member) without IdP gating. No record of when someone was granted access. Revocation requires a person to remember to remove the user.
Fix
IdP groups gate all CI access. Group membership is the source of truth. Access reviews run quarterly, output flows to the central log account.
§ 164.312(a)(1) · Access control

Phishing-resistant MFA is enforced at the deploy gate.

"Show me the MFA challenge for this production deploy."

Passes
WebAuthn or FIDO2 enforced at the IdP for any session that can trigger a production deploy. SMS-based or app-based MFA is not sufficient for production-PHI paths. The MFA event is logged with the same identity that appears on the deploy.
Fails
SMS MFA only. MFA at IdP login but no re-challenge for high-risk actions. Service accounts bypassing MFA via static tokens.
Fix
Phishing-resistant MFA enforced at IdP. Step-up authentication required for any role that can write to a PHI-bearing environment. Log the auth event in the same store that holds deploy events so the auditor can join them on identity and time.

The structural pattern underneath all three: no human credential survives longer than the pipeline run that uses it. Every action is attributable to a named identity that exists in your corporate IdP. The CI system is downstream of identity, not a parallel identity store.

04 — Audit loggingEvery deploy emits tamper-evident evidence.

HIPAA § 164.312(b) is one of the few Security Rule sections that names the requirement directly: "implement hardware, software, and/or procedural mechanisms that record and examine activity in information systems that contain or use electronic protected health information." For a pipeline, that means every deploy event, every signature verification, every policy decision, and every access grant lands in a log that engineers cannot edit.

§ 164.312(b) · Audit controls

Logs are centralized in an account engineers cannot write to.

"Show me the deploy event for this production release, with the approver identity and timestamp."

Passes
A dedicated logging account (AWS), project (GCP), or subscription (Azure) with S3 Object Lock or equivalent retention lock. Production accounts write logs; nobody in production can read or delete them. CloudTrail organization trail captures every admin action with the assumed-role chain intact.
Fails
Pipeline logs only in the CI run output, expiring after 30-90 days. Logs in the same account where deploys happen. CloudTrail enabled but writable by the same role that performs deploys. "We ship to Datadog" with no retention policy mapped to the regulation.
Fix
Centralized logging account with S3 Object Lock in compliance mode, retention configured to your HIPAA retention requirement (typically 6 years for documents under § 164.316(b)(2), longer in practice). Cross-account replication is one-way: production writes, logging stores, nobody deletes.
§ 164.312(b) · Audit controls

Every deploy is queryable by identity, environment, and artifact hash.

"Show me every production deploy this user made in Q1, and the SHA-256 of the artifact deployed."

Passes
Pipeline emits a structured deploy event on every run: who, when, what (artifact digest), where (environment), why (change ticket reference). The event lands in the logging account with the same retention as access logs. The auditor can answer the query above with one SQL or Athena query.
Fails
Deploy history lives in the CI tool only (GitLab pipelines, GitHub Actions runs). Artifact hashes are not recorded against the deploy event. Answering the query requires correlating five systems and a Slack search.
Fix
Pipeline writes a structured deploy event to the logging account at the moment of cutover. Schema: deploy_id, timestamp, actor_identity, environment, artifact_digest, change_ticket, approval_chain. Treat it as a first-class output of the pipeline, not telemetry.

05 — Integrity controlsEvery artifact deployed has a signature you can verify.

§ 164.312(c)(1) requires "policies and procedures to protect electronic protected health information from improper alteration or destruction." For pipelines, that is the supply chain: from the source commit to the running container, you have to be able to demonstrate that what is in production is what was reviewed and approved.

I recommend Cosign for signing container images. The Sigstore ecosystem has matured to the point where Cosign integrates with KMS-backed signing keys natively, and the verification policy lives in admission control where it can fail closed. Do not use Docker Content Trust for new HIPAA pipelines. Notary v1 is effectively unmaintained, and the verification story does not survive auditor questioning.

§ 164.312(c)(1) · Integrity

Container images are signed before deploy and verified on admission.

"Show me the signature for this container, the key used to sign it, and the admission decision that allowed it into production."

Passes
Cosign or equivalent signs every image at build time using a KMS-backed key. The cluster admission controller (Kyverno or OPA Gatekeeper) verifies the signature against the trusted public key. Unsigned or improperly-signed images are rejected at admission, the rejection logged.
Fails
Images deployed without signature verification. Signing keys held in a developer's keyring or in plaintext in the CI environment. Signature checks performed in CI but not enforced at the cluster.
Fix
Cosign signing at build with a KMS-stored key. Kyverno admission policy enforcing verification at the cluster. Drift detection comparing running images against the signed-and-approved list.

The admission policy itself is short and worth showing. This is the Kyverno-equivalent pattern in OPA Rego, derivative from public Sigstore examples and Stonebridge's reference patterns:

# File: policies/hipaa/admission/signed_images.rego
# Enforces signed-image admission for any pod entering a PHI-bearing namespace.
# Maps to 45 CFR § 164.312(c)(1) integrity controls and § 164.308(a)(4)
# information access management for production-PHI workloads.

package kubernetes.admission

import future.keywords.if
import future.keywords.in

# Namespaces that hold PHI workloads. The deny list is explicit so a
# misconfigured namespace cannot accidentally accept unsigned images.
phi_namespaces := {"prod-phi", "staging-phi", "validation-phi"}

# Public keys we trust. In production these live in a ConfigMap mounted
# at runtime, sourced from KMS public key endpoints.
trusted_keys := {
  "cosign-prod-key-2026": "-----BEGIN PUBLIC KEY-----...",
  "cosign-prod-key-2025-rotation": "-----BEGIN PUBLIC KEY-----...",
}

# Hard deny: any image in a PHI namespace without a verified signature
# from a trusted key fails admission. The reason string lands in the
# audit log so the rejection is queryable.
deny[msg] if {
  input.request.namespace in phi_namespaces
  some container in input.request.object.spec.containers
  not image_signed_by_trusted_key(container.image)
  msg := sprintf("HIPAA integrity violation: image %v not signed by trusted key in namespace %v (45 CFR 164.312(c)(1))", [container.image, input.request.namespace])
}

# Soft warning: even non-PHI namespaces should reject unsigned images.
# A warning lets the platform team see drift without breaking dev.
warn[msg] if {
  not input.request.namespace in phi_namespaces
  some container in input.request.object.spec.containers
  not image_signed_by_trusted_key(container.image)
  msg := sprintf("Unsigned image %v in non-PHI namespace %v. Cluster baseline requires signatures.", [container.image, input.request.namespace])
}

# Helper: returns true if any trusted key verified the image signature.
# The actual verification happens in a sidecar that pre-populates the
# image annotations with verification results. This keeps Rego pure.
image_signed_by_trusted_key(image) if {
  annotation := input.request.object.metadata.annotations[sprintf("cosign.verified/%v", [image])]
  annotation.verified == true
  annotation.key_id in object.keys(trusted_keys)
}

The policy fails closed. A PHI-bearing namespace will not accept an unsigned image, period. The denial message includes the CFR citation so when the auditor pulls the admission log, the regulatory mapping is already in the record. The longer write-up of the parent-child pipeline architecture that produces signed artifacts in the first place is in the HIPAA CI/CD implementation guide.

06 — Transmission securityModern TLS, mutually authenticated where it matters.

§ 164.312(e)(1) requires safeguards against unauthorized access during transmission. For pipelines, the relevant transmission paths are the CI-to-registry path, the registry-to-cluster path, the cluster-to-PHI-database path, and the deploy-evidence-to-logging-account path. Each needs encryption in transit; the PHI-bearing paths need mutual authentication.

§ 164.312(e)(1) · Transmission security

Encrypted transit for every PHI-bearing path, with mutual auth where the threat model warrants.

"Show me the TLS configuration for the path between the pipeline and the production database. Which ciphers are accepted? Is the client authenticated?"

Passes
TLS 1.2 minimum, TLS 1.3 preferred. Modern cipher suites only. Mutual TLS (mTLS) on internal PHI-bearing service-to-service calls, typically via a service mesh (Istio, Linkerd) or platform-native (AWS App Mesh, GCP Cloud Service Mesh). Private connectivity (PrivateLink, Private Service Connect) where cross-network paths exist.
Fails
TLS 1.0 or 1.1 still accepted on any PHI-touching endpoint. Plain-HTTP internal calls. Service-to-service auth via bearer tokens with no transport-level identity. Network ACLs treated as the encryption layer.
Fix
Enforce TLS 1.2+ at every load balancer. Adopt a service mesh for internal mTLS. Use private connectivity for cross-VPC PHI paths. Run a scheduled scanner against your endpoints (sslyze, testssl.sh) and ship the report to the evidence bucket.

07 — Continuous evaluationScanners as policy gates, not as advisory notifications.

§ 164.308(a)(8) requires periodic technical evaluation of the security posture. The way that maps to pipelines is straightforward: scanners run on every change, the results gate deploys, and the findings flow into the evidence trail. Auditors will look for five scanner types in a HIPAA pipeline. Each maps to a category of risk; missing any one is a finding.

Scanner type Recommended tool What it catches Maps to
SAST Semgrep, CodeQL Source-code vulnerabilities in your application § 164.308(a)(8)
SCA OSV-Scanner, Snyk Known CVEs in third-party dependencies § 164.308(a)(8), § 164.312(c)(1)
Container CVE Trivy, Grype Vulnerable OS packages and libraries in container images § 164.308(a)(8)
IaC tfsec, Checkov Misconfigured cloud resources, public buckets, open security groups § 164.312(a)(1), § 164.312(e)(1)
Secrets Gitleaks, TruffleHog Hardcoded credentials, API keys, tokens in source § 164.308(a)(4)

The crucial structural detail: scanners are policy gates, not advisory notifications. A CVE result that sends a Slack message and lets the deploy proceed is not a control. The gate has to fail closed. The pattern looks like this in GitHub Actions, derivative from public open-source patterns:

# File: .github/workflows/hipaa-build.yml
# Build, scan, and gate. Every scanner is a policy gate, not a notification.
# Maps to 45 CFR § 164.308(a)(8) continuous evaluation and § 164.312(c)(1)
# integrity. Failed gates block deploys; results emit to the evidence bucket.

name: HIPAA pipeline

on:
  push:
    branches: [main]

jobs:
  scan:
    runs-on: self-hosted-hipaa-baseline   # Hardened, network-isolated runner
    steps:
      - uses: actions/checkout@v4

      - name: SAST (Semgrep)
        run: semgrep --config p/hipaa --error --json > sast.json

      - name: SCA (OSV-Scanner)
        run: osv-scanner --format json --output sca.json ./

      - name: Container CVE (Trivy)
        run: trivy image --severity HIGH,CRITICAL --exit-code 1 --format json --output trivy.json ${{ env.IMAGE }}

      - name: IaC (Checkov)
        run: checkov -d ./terraform --output json --output-file iac.json --soft-fail false

      - name: Secret scan (Gitleaks)
        run: gitleaks detect --no-git -v --report-format json --report-path secrets.json

      # Policy gate. Any HIGH/CRITICAL finding from any scanner blocks the
      # pipeline. The gate runs after every scanner so partial failures are
      # visible in the run log.
      - name: HIPAA policy gate
        run: |
          python3 .ci/policy_gate.py \
            --sast sast.json \
            --sca sca.json \
            --trivy trivy.json \
            --iac iac.json \
            --secrets secrets.json \
            --baseline hipaa-2026

      # Evidence emit. Every scanner output is signed and pushed to the
      # retention-locked evidence bucket. This is the artifact the auditor
      # will read, so the schema is stable and queryable.
      - name: Emit signed evidence
        run: |
          cosign attest --predicate sast.json     --type vuln $IMAGE
          cosign attest --predicate sca.json      --type vuln $IMAGE
          cosign attest --predicate trivy.json    --type vuln $IMAGE
          aws s3 cp ./*.json s3://hipaa-evidence-prod/pipeline-runs/${{ github.run_id }}/

Three things to notice. First, the runner itself is a hardened, network-isolated self-hosted runner. Public hosted runners reaching production PHI infrastructure is a finding on its own. Second, every scanner output is signed (Cosign attest) before being stored, so the evidence has its own integrity chain. Third, the policy gate is a script, not a YAML flag. The script encodes the baseline in version control, can be unit tested, and the failure conditions are auditable.

08 — Environment isolationThe runner that builds dev cannot reach prod.

The single biggest pipeline-level finding I see in HIPAA-environment audits is runners that can reach environments they should not. A pipeline runner with credentials for production, used to build a dev branch, is the textbook example of why the network and identity layers have to be scoped per environment.

§ 164.308(a)(4), § 164.312(a)(1)

Per-environment runners with scoped IAM and explicit egress.

"Show me which runner deployed this artifact, and demonstrate the runner cannot reach any other environment."

Passes
Separate runner pool per environment (dev, staging, prod-PHI). Runners run on dedicated nodes with environment-scoped IAM roles. Egress is controlled by VPC Service Controls (GCP), AWS PrivateLink, or equivalent. A dev runner trying to reach prod-PHI gets a network denial, not an IAM denial.
Fails
Shared runner pool. Runner credentials with permissions across environments. "We use namespaces" as the only isolation. CI runner with internet egress to anywhere.
Fix
Dedicated runner pools per environment. IAM scoped to the single account the runner serves. Egress allowlist per runner. Network policy at the cluster level if runners run on Kubernetes.

09 — Evidence collection and retentionThe audit trail has to outlive the pipeline that created it.

Evidence retention is where most pipelines fail the audit even when the pipeline itself is well-built. CI tools rotate their run logs aggressively (30 to 90 days by default). HIPAA documentation retention is six years under § 164.316(b)(2). The arithmetic does not work, so the evidence has to live outside the CI tool from the moment it is produced.

The pattern: every pipeline run emits a structured set of artifacts (deploy event, scanner outputs, signature attestations, policy decisions) to an evidence bucket in a separate account, with retention locks configured. The Terraform for that bucket is short, and worth getting right:

# File: terraform/hipaa-evidence/main.tf
# Retention-locked evidence bucket for HIPAA CI/CD pipeline artifacts.
# Maps to 45 CFR § 164.312(b) audit controls and § 164.316(b)(2)
# documentation retention. The bucket lives in a dedicated logging
# account; production accounts have write-only access via a scoped role.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

# Evidence bucket. Object Lock in COMPLIANCE mode means even the root
# account cannot delete objects within the retention window. This is
# the property that satisfies the auditor's "can engineers tamper with
# the evidence?" question.
resource "aws_s3_bucket" "hipaa_evidence" {
  bucket              = "hipaa-evidence-${var.env}-${var.account_suffix}"
  object_lock_enabled = true

  tags = {
    Purpose      = "HIPAA pipeline evidence"
    CFRSection   = "164.312(b),164.316(b)(2)"
    Retention    = "6y"
  }
}

# Retention configuration. COMPLIANCE mode is non-negotiable for HIPAA
# evidence. GOVERNANCE mode lets privileged users override; that is a
# finding waiting to happen.
resource "aws_s3_bucket_object_lock_configuration" "hipaa_evidence" {
  bucket = aws_s3_bucket.hipaa_evidence.id

  rule {
    default_retention {
      mode = "COMPLIANCE"
      days = 2190  # 6 years; matches § 164.316(b)(2) documentation retention
    }
  }
}

# Versioning is a prerequisite for Object Lock. Without it the lock
# applies to a single object that can be overwritten with a new version.
resource "aws_s3_bucket_versioning" "hipaa_evidence" {
  bucket = aws_s3_bucket.hipaa_evidence.id
  versioning_configuration {
    status = "Enabled"
  }
}

# Encryption at rest with a customer-managed key. The key policy denies
# deletion by anyone but a designated break-glass role with MFA.
resource "aws_s3_bucket_server_side_encryption_configuration" "hipaa_evidence" {
  bucket = aws_s3_bucket.hipaa_evidence.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "aws:kms"
      kms_master_key_id = aws_kms_key.hipaa_evidence.arn
    }
    bucket_key_enabled = true
  }
}

# Public access is blocked at the bucket level. There is no scenario in
# which HIPAA evidence should be public, so the block is total.
resource "aws_s3_bucket_public_access_block" "hipaa_evidence" {
  bucket                  = aws_s3_bucket.hipaa_evidence.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

The key property is Object Lock in COMPLIANCE mode. Once an object lands in this bucket, no one can delete it inside the retention window. Not the engineering team, not the platform team, not the root account. That is the architectural property that turns "we keep our evidence" into a verifiable statement. The same pattern translates to GCS Bucket Lock and Azure Immutable Blob Storage.

The cross-cutting principle here is one of the architectural decisions in the pipeline architecture pattern Stonebridge uses: the evidence outlives the pipeline that produced it, and lives where the pipeline cannot reach back to modify it. That is what makes the audit trail trustworthy under scrutiny.

10 — Change managementApproval chains that survive auditor questioning.

Every production deploy needs an approval chain that ties a named human to the artifact being deployed. The relevant question from § 164.308(a)(1)(ii)(B) is whether your sanction policy can be enforced: if a developer deploys an unreviewed change to a PHI environment, can you identify who, what, and when after the fact. If the answer is "we would have to dig," the control fails.

§ 164.308(a)(1)(ii)(B), § 164.312(b)

Production deploys require named-human approval, recorded against the artifact.

"For this production deploy, show me who approved, what they approved, and the change ticket they referenced."

Passes
Production environment is a protected environment in GitHub or a protected branch in GitLab. Approval is required from a named human in a defined approver group, not the deploy author. The approval event records the approver identity, the artifact digest, and the linked change ticket. The chain lands in the evidence bucket.
Fails
Auto-deploy from a green build. Approval clicks with no identity ("approved by user 'admin'"). Approver can be the same person who authored the change. The approval lives in the CI tool only and expires with the run log.
Fix
Protected environment with required reviewers from a separate approver group. The approval webhook emits a structured event into the evidence bucket, joining the approver identity, the artifact digest, and the change ticket reference. Treat the approval chain as a first-class deploy output.

11 — A representative engagementWhat we found at a 32-host healthcare platform on GCP.

I worked with a healthcare platform team running production workloads on GCP across roughly 32 VM-backed services that mixed Tomcat, Node.js, and OS versions in ways nobody had inventoried. Their compliance officer had a required baseline (Tomcat 9.0.62+, Node.js 18+, Ubuntu 20.04+). Their auditor was scheduled in five weeks. They did not know which hosts complied.

The first day we pulled their pipeline configurations and ran the evidence pull. The pipeline shipped well. Tests ran. Containers were built. The platform was stable. But: every deploy ran under a CI service account with full project-level IAM. The signing chain did not exist. Scanner output lived in pipeline artifacts that aged out after 90 days. The deploy event was not stored anywhere outside the CI tool. They had every individual capability needed to pass the audit, just not connected in the way the Security Rule expected.

We split the remediation into two parallel tracks. Track one: write an Ansible and Python tool that connected to each VM through GCP Identity-Aware Proxy, scraped the running versions of Tomcat, Node.js, and OS, and produced a compliance matrix mapping each host to the required baseline. That gave the compliance team the inventory they needed inside the first week instead of the four weeks a manual walk would have taken. Track two: rebuild the pipeline so the same baseline could not regress. We added Cosign signing with a KMS-backed key, Trivy and OSV-Scanner as policy gates that failed closed, Workload Identity Federation to eliminate the long-lived service account, a centralized logging account with Object Lock at 6-year retention, and a deploy-event emitter that wrote structured records to the evidence bucket on every cutover.

The audit cleared on first-party review. The compliance team kept the inventory tool as part of their continuous monitoring practice. The pipeline architecture is what the HIPAA CI/CD service page describes generically, but the engagement-specific detail that mattered: the baseline enforcement happens at plan time, not at deploy time. By the time the pipeline tries to ship a non-compliant container, the policy gate has already rejected the build. Future regressions are structurally impossible.

The pattern translates directly to AWS (CloudTrail organization trail + S3 Object Lock + IAM Identity Center) and Azure (Activity Log + Immutable Blob Storage + Entra ID federation). Where the integration patterns differ across SOC 2 and HITRUST is covered in the HIPAA CI/CD vs SOC 2 CI/CD post; the structural pattern is the same.

12 — The five questions auditors always askPre-answer these, walk into the audit lighter.

Across roughly a dozen HIPAA-environment engagements over the last few years, these five questions come up in some form every single time. Pre-answering them in your runbook is the single highest-leverage prep activity for an audit. Each maps to a control family already covered above; the value is having the answer in one paragraph that a non-engineer can read aloud to an assessor.

  1. "Show me, by named human, who can deploy to a production-PHI environment, and when each person was last reviewed for that access." The answer should be one query against the IdP plus one against the access-review log. If the answer involves grepping CI runners, the architecture is wrong.
  2. "For this specific production deploy from last Tuesday, show me the approval chain, the artifact signature, and the scanner results." The answer should be one query against the evidence bucket using the deploy ID. Three artifacts come back: the approval event, the signature attestation, and the scanner outputs.
  3. "Can engineers in the production account read or modify the audit log?" The answer should be "no, the logs live in a separate account, retention-locked, write-only from production." If you have to qualify the answer, the architecture is wrong.
  4. "What happens if a scanner finds a CRITICAL CVE during a production deploy?" The answer should be "the deploy blocks. The policy gate fails closed. We have a documented exception process that requires named-human approval and is itself logged as evidence."
  5. "Show me a deploy from six months ago, and prove the running container today matches what was approved then." The answer should be a signature verification against the image currently running, plus the historical signing event from the evidence bucket. Drift detection is the supporting control.

If your team cannot answer all five in under five minutes per question with documentation, the audit will surface that. Better to surface it in your own dry-run two weeks ahead.

13 — Common gapsThe patterns we see every engagement.

Quick gap list · cross-reference

Long-lived service account credentials. Any credential that lives longer than the pipeline run that uses it is a finding. OIDC federation removes the entire category.

Logs in the same account as production. The most common single finding. Move them to a logging account with retention locks the day you start the audit prep.

Scanners as Slack notifications. Advisory scanners are not controls. The gate has to fail closed.

No deploy event outside CI. CI run logs expire. The deploy event has to live in the evidence bucket from the moment of cutover.

Approval workflow that lets the author approve. The approver and the author must be different humans. Required-reviewer configuration handles this in GitHub and GitLab.

Unsigned images in production. Cosign-signed images verified at admission. Anything less invites the question "how do you know what is running."

Most of these are structural choices made early that compound into hard-to-fix gaps. The longer write-up of the patterns most often missed lives in 5 mistakes healthcare teams make on HIPAA CI/CD.

14 — ClosingThe architecture has to answer the question.

Every control in this checklist reduces to the same property: the pipeline architecture makes the auditor's question answerable in seconds. Identity, integrity, audit trail, evidence retention, scanner gates, approval chains. Each is a touchpoint where the pipeline either has the answer or it does not.

The teams that ship well in regulated environments are not the ones with the most paperwork. They are the ones whose architecture makes compliance violations structurally difficult and whose evidence emits as a property of how the pipeline runs. That is what an auditor recognizes as a mature compliance posture, and it is also what lets engineering keep shipping while compliance reviews happen in parallel instead of in series.

If you are walking into a 3PAO assessment, a customer security review, or a HITRUST readiness pass: Stonebridge runs 2-week HIPAA CI/CD audits built around this exact checklist. Fixed fee, founder-led, the deliverable is a written control map plus a prioritized remediation roadmap your team can act on. We sign BAAs as part of the engagement and the report holds up under first-party review by your auditor.


About the author

Lucas Jones, Founder

Founder and Principal Platform Engineer at Stonebridge Tech Solutions. Six years building cloud infrastructure and CI/CD pipelines in regulated environments, including HIPAA, FedRAMP, and SOC 2 work for healthcare and defense engineering teams across AWS, GCP, Azure, and OCI.

Based in Sacramento, California. The work that sits behind this checklist is what Stonebridge does as a fixed-fee engagement.

See how we engage on HIPAA CI/CD work →

Walking into an audit and not sure what will hold up?

Most discovery calls take 30 minutes. We come back with a written proposal within 48 hours. If we are not the right fit for the engagement, we will tell you in the first call and point you somewhere that is.

Book a 30-minute call