Skip to content
8 min read

SOC 2 separation of duties for a two-engineer team

SOC 2 separation of duties can work with two engineers when approvals, deployments, access reviews, and exceptions are enforced and evidenced.

SOC 2 separation of duties for a two-engineer team
Table of Contents

SOC 2 separation of duties can work with two engineers when authority is split across people, protected workflows, and service identities. It does not work when both engineers remain administrators everywhere and a policy document claims they wear different hats. The control must stop or expose a conflicting action at the moment it happens.

A fractional CTO gives a small team an independent approver and control owner without adding another full-time engineer. That person should not become a ceremonial name in a responsibility chart. The CTO must review sensitive access, approve defined classes of production change, inspect exceptions, and leave evidence an auditor can sample.

SOC 2 does not prescribe a headcount

The AICPA Trust Services Criteria ask an organization to meet control objectives, not to hire a minimum number of employees. CC6.1 addresses logical access over protected information assets. CC8.1 addresses authorization, design, development, configuration, documentation, testing, approval, and implementation of changes. Neither criterion says that a developer, reviewer, deployer, and access reviewer must be four full-time employees.

That distinction matters because founders often turn a useful control idea into an imaginary staffing rule. Separation of duties is about incompatible authority. If one person can write a change, approve it, release it, erase the deployment record, and keep permanent production access, the company depends on that person's restraint. Renaming the same person "developer" in one row and "release manager" in another changes nothing.

NIST SP 800-53 control AC-5 makes the idea more explicit. It tells organizations to identify and document the duties that require separation, then define access authorizations that support that separation. I use NIST here as a practical design reference, not as a claim that every SOC 2 audit requires the NIST control set. Its wording directs attention to permissions and evidence instead of job titles.

A small company should define which combinations create unacceptable risk. Those combinations usually include:

  • authoring and finally approving the same production change;
  • requesting and granting one's own privileged access;
  • performing and closing the review of one's own access;
  • changing audit settings and controlling the only copy of the logs;
  • using an emergency bypass and approving that bypass afterward.

Two engineers can cover ordinary peer review for each other. A fractional CTO can cover access governance, sensitive approvals, and exception review. CI/CD can perform repeatable releases through a service identity. This arrangement separates decisions and actions even though the payroll remains small.

The auditor still judges whether the design fits the service, risks, and audit scope. Discuss the proposed matrix with the audit firm before the observation period starts. An auditor may accept a well-enforced small-team design and reject a larger team's loose process.

Split authority before assigning names

Start with the four duties in the actual delivery path: develop, approve, deploy, and review access. Assign the minimum authority needed for each duty, then put names against those roles. Do not start with employee titles and invent distinctions afterward.

For a typical two-engineer SaaS team, the operating map can use four roles:

  • Both engineers may write application changes. Each may approve the other engineer's pull request, but neither may supply the independent approval for their own latest change.
  • After approval, either engineer may merge to the protected branch and start the production workflow. Starting a workflow is not the same as executing arbitrary production commands.
  • The fractional CTO approves sensitive paths, privileged access, and exceptions. The CTO also owns the periodic review of human and service access.
  • The CI/CD service identity executes deployments and writes records. It runs required checks but cannot approve code or grant human access.

This matrix separates authorization from execution. An engineer may start a deployment, but the pipeline performs it with a narrowly scoped credential. For routine changes, the peer's pull request approval supplies the independent decision. For a database migration, authentication change, infrastructure policy, or emergency exception, the fractional CTO supplies another approval.

Write down what "sensitive" means. A label such as "high risk" gives people room to classify inconvenient changes as routine. Use paths and events that a tool can detect: identity and authorization code, infrastructure definitions, production workflow files, database migrations, audit logging, encryption settings, billing logic, and permission changes.

The CTO does not need to approve every typo or dependency patch. That would create a queue, encourage bypasses, and make the control look active while everyone treats it as an obstacle. The CTO owns the policy, the sensitive path list, access reviews, and exceptions. Peer approval plus automated checks handles ordinary releases.

Independence must exist for the action under review. A fractional CTO who wrote a change should not provide its independent approval. In that case, one engineer reviews the CTO's change, and the other engineer or a designated executive approves the production release if the risk calls for it. The matrix should state this alternate path instead of pretending the conflict will never happen.

A responsibility matrix and a permission matrix answer different questions. The responsibility matrix says who should act. The permission matrix says who can act in each system, including administrator and bypass capabilities. Auditors often find a clean first matrix beside a dangerous second one.

Build the permission matrix from live exports. For each repository, cloud account, production environment, database, and logging destination, list who can administer the system, change access, approve work, execute a release, and alter evidence. Compare that state with the operating map and remove permissions that contradict it.

Temporary assignments need the same discipline. If Engineer B covers the CTO during leave, record the start, end, approved scope, and access change. Do not leave the alternate role active indefinitely. A quarterly review cannot compensate for a temporary administrator grant that quietly became permanent.

Protected workflows must carry the separation

The repository and delivery system should enforce the matrix because a written procedure cannot stop a tired administrator from pressing the wrong button. Protect the production branch, block direct pushes, require a pull request, require approval from someone other than the last person who pushed, and require tests before merge.

GitHub's protected branch documentation says required reviews can prevent merging until an authorized reviewer approves. It also warns that administrators bypass branch protection by default unless the rule disallows bypass. That default is where many small-team designs fail. A screenshot of a branch rule means little if both engineers can ignore it without generating an exception.

The equivalent settings differ by repository provider, but the expected state is stable:

production_branch:
  direct_push: blocked
  required_approvals: 1
  last_pusher_may_approve: false
  dismiss_stale_approvals: true
  required_checks:
    - unit-tests
    - security-scan
  administrator_bypass: blocked
sensitive_paths:
  - "infra/**"
  - "db/migrations/**"
  - ".ci/production/**"
  - "src/auth/**"
  required_owner: fractional-cto

This is a control specification, not a promise that a vendor accepts these exact field names. Translate it into repository rules, a ruleset, protected branches, or the provider's equivalent. Save an exported configuration or API response that proves the live settings match the specification.

Code ownership helps route sensitive files to the CTO, but routing alone is not approval. Confirm that the branch rule requires a code owner review and that administrators cannot dismiss the review or push around it. Test the negative case: have Engineer A open a pull request, approve it using Engineer A's account, and attempt to merge. The system should reject the merge.

Run that negative test after material configuration changes and at a defined interval. Keep the run identifier, actor, repository, attempted action, and rejection result. A control test that only confirms successful merges misses the behavior the control exists to prevent.

Protect the control configuration itself. Repository rules, code owner files, workflow definitions, environment settings, and identity groups can all weaken the gate. Changes to those objects should require the CTO or another independent owner, and the audit log should record who changed them.

Review provider behavior before relying on a checkbox. Some settings apply only to selected branches, paid plans, repository types, or users without administrator rights. Document the tested behavior in your own account. A sales page or generic manual cannot prove that your production repository rejected a bypass.

Keep a small inventory of enforcement points with an owner and a verification method. For the repository, verify branch and review rules. For CI/CD, verify who can edit workflows and use production credentials. For the cloud, verify deployment roles and console administrators. For logging, verify writers cannot delete retained events.

AI-generated changes follow the same path. Claude Code, Codex, or another coding agent can prepare a branch and tests, but its output belongs to the human or service identity that submitted it. An agent account must not become a convenient second "person" that approves work requested by the same engineer.

Deployment is a separate control point

Production deployment should use a service identity that receives an approved artifact, not a human administrator copying files from a laptop. That identity should have permission to deploy the build and little else. Engineers may trigger the workflow, but they should not possess the production credential used by the job.

Keep build and release provenance connected. The deployment record should identify the commit or immutable artifact, pull request, approving user, workflow run, target environment, start time, result, and initiating user. If the system rebuilds after approval, an unreviewed dependency or source change can enter the release. Promote the artifact that passed review and tests.

A protected production environment adds a second gate for high-risk releases. GitHub's environment documentation, for example, supports required reviewers and an option that prevents the person who initiated a deployment from approving it. It can also withhold environment secrets until approval. Other delivery tools offer similar controls, though plan limits and exact behavior vary.

Use that gate selectively. A practical policy is:

  1. Every production release requires a reviewed pull request and passing checks.
  2. Sensitive changes also require the fractional CTO as code owner or environment approver.
  3. The CI/CD identity deploys the approved artifact and writes an immutable or externally retained record.
  4. A failed deployment creates an incident or change record instead of an undocumented manual repair.

Do not give both engineers standing console administrator access because "someone might need it." Use time-limited elevation where the infrastructure supports it. If it does not, store an emergency credential separately, monitor its use, and review each use after the incident.

There is a subtle conflict between operational availability and perfect independence. With two engineers, the peer reviewer may be asleep or unavailable during an outage. The answer is not to deny the conflict. Define a break-glass path that permits a single engineer to restore service, records the bypass automatically, alerts the CTO, and requires independent review within a stated period.

An auditor will ask whether people actually followed the documented path during the observation window. One clean architecture diagram will not offset a month of console deployments. Remove the easy manual path, or every urgent release will eventually use it.

Access review needs an independent owner

Make sensitive approvals somebody's job
Bring in a fractional CTO to own the decisions your two engineers cannot review independently.

The fractional CTO should own the review of privileged human and service access because neither engineer can independently close a review that includes their own account. Each engineer can explain why an entitlement exists. The CTO decides whether the explanation matches current duties and records removal, reduction, or acceptance.

CC6.1 focuses on restricting logical access through software and rules. NIST AC-6 adds the useful principle of least privilege: users and processes receive only the access needed for assigned tasks. Together, they point to a review that covers actual entitlements, not a spreadsheet of expected roles.

Collect system-generated account and role exports from every in-scope system. Typical sources include the identity provider, cloud organization, source control organization, CI/CD system, production database, observability tools, support console, secrets manager, and any platform that can change customer data or security settings.

For each account, record:

  • the named owner, account type, and authentication method;
  • assigned roles and privileged group membership;
  • business reason and approving person;
  • last activity where the system provides it;
  • the review decision and completed remediation.

Service accounts deserve the same attention as people. Name an owner, state the workload, restrict the credential, and check whether the service still runs. A token called deploy-prod with no owner and organization-wide administration is an access finding waiting to happen.

Pick a frequency based on risk and state it in policy. Many small organizations review privileged production access more often than low-risk application access. SOC 2 does not supply a universal "quarterly" rule for every account, so do not copy that interval without thinking. The audit firm will test whether your chosen frequency is reasonable and whether you met it.

The review package should preserve the source export, review date, reviewer, decisions, and remediation evidence. A typed list recreated for the auditor cannot prove completeness. If the export came from an API, retain the query or command and its execution record so someone can reproduce the population.

The CTO's own access needs another reviewer. Assign the CEO, founder, or another authorized executive to review the CTO's privileged roles. If no qualified internal person can evaluate the technical detail, the executive can verify business need while an external security adviser checks the permission level. Nobody should approve their own line item.

Evidence should fall out of the workflow

Good evidence comes from the systems that enforce the control, with enough context to connect policy, population, sample, and result. A folder of screenshots assembled before fieldwork costs time and often hides missing weeks.

NIST SP 800-53A's AC-5 assessment procedure is useful even when the company does not claim NIST compliance. It tells an assessor to examine separation procedures, system configuration, access authorizations, duty assignments, and audit records, then test the automated mechanisms. That is a better preparation list than "show the auditor our policy."

Create an evidence manifest for each control period. It can be a CSV, ticket table, or JSON object. The fields matter more than the format:

{
  "control_id": "CHG-02",
  "period": "2026-Q2",
  "population_query": "production deployments from delivery API",
  "population_count": 47,
  "artifacts": [
    "branch-rule-export.json",
    "deployment-population.csv",
    "exception-register.csv"
  ],
  "owner": "fractional CTO",
  "reviewed_at": "2026-07-08"
}

Those values are illustrative, not claims about a real company. Your manifest should point to retained artifacts and reconcile the total deployment population to the source system. If the API returns 47 deployments and the evidence table has 46, investigate the difference before the auditor selects a sample.

For change management, retain the pull request, reviews, check results, merge record, artifact identifier, deployment record, and any exception. For access reviews, retain the raw account exports, normalized review sheet, sign-off, and proof that removals occurred. For break-glass use, retain the alert, incident timeline, commands or actions taken, and retrospective approval.

Evidence also needs protection. If the two engineers can alter the only audit log that records their administrator activity, the log cannot provide strong independent evidence. Send important identity, cloud, repository, and deployment events to a log destination with separate permissions and retention. The CTO may review alerts and exports without holding broad operational access.

Test completeness, not just appearance. Choose one production deployment from the runtime or cloud event history and trace it backward to the delivery record, artifact, commit, pull request, and approval. Then choose one merged production change and trace it forward to the deployment or documented cancellation. The two directions catch missing manual releases and approved changes that never shipped.

Define populations before fieldwork. "All changes" could mean merged pull requests, production workflow runs, cloud configuration events, database migrations, or customer-facing releases. State which source is authoritative and how related sources reconcile. If multiple repositories feed one service, the population query must include all of them.

Avoid evidence that depends on a mutable display. Pull request pages and dashboards can change after the control operates. Export the underlying event or API response when practical, retain it under controlled permissions, and record the query time. Screenshots can add context, but they should not be the only proof when structured records exist.

Make samples easy to trace by using stable identifiers. Put the commit hash or artifact digest in the deployment record, the workflow run in the change ticket, and the access review identifier in each remediation ticket. An auditor should be able to move through the chain without matching timestamps by hand.

A paper matrix fails when administrators can bypass it

Put an owner on access reviews
Fractional CTO leadership gives your two-engineer team an independent reviewer for privileged access.

The most common small-team failure starts with a sensible diagram and ends with universal administrator rights. Engineer A writes a migration. Engineer B approves the pull request. Engineer A merges it, opens the cloud console, edits the production job, runs the migration manually, and later adds a ticket saying the deployment succeeded. The CTO reviews a monthly spreadsheet built from those tickets.

The pull request approval proves only that someone reviewed the source change. It does not prove that production received the reviewed artifact, that the deployment job stayed unchanged, or that the person executing the change lacked power to alter the record. The monthly spreadsheet repeats assertions made by the same people whose work it is supposed to check.

Fix the chain at each authority boundary. Protect the workflow definition as a sensitive path. Make the pipeline select an immutable artifact. Restrict production changes to its service identity. Export cloud and deployment logs outside the engineers' normal administration. Have the CTO sample the system population rather than a hand-curated list.

Another popular recommendation is to create separate accounts for "developer" and "release manager" while giving one engineer both passwords. Separate usernames can improve logging, but they do not separate duties when one person controls both identities. Use separate accounts to enforce least privilege and explicit elevation, not to manufacture independence.

The same problem appears when a founder approves every change without understanding it. Independence does not mean ignorance. An approval should address a defined question: Was the change reviewed by someone competent? Did the approved artifact reach production? Is the requested access consistent with the person's role? A ceremonial approval adds latency and weak evidence.

When a conflict cannot be prevented, use a compensating control that detects it quickly and independently. For example, allow an emergency deploy by one engineer, send the event to a protected log, notify the CTO automatically, require a retrospective review, and track repeat use. "Management reviews activity" is too vague. State who reviews which population, how often, what evidence they inspect, and how exceptions close.

Emergencies need a designed exception

Price the smallest workable team
The five-day Team & AI Audit identifies savings before you expand the engineering team.

A two-engineer company will eventually face an outage while the normal approver is unavailable. A control design that assumes perfect attendance will be bypassed. The exception path should restore service without turning every inconvenient release into an emergency.

Define the permitted triggers, such as active customer impact, a confirmed security incident, or a failed release that needs immediate rollback. Missed deadlines and an impatient founder do not qualify. Limit the action to rollback, disablement, or the smallest repair that restores a safe state.

The break-glass workflow should capture the actor, reason, incident identifier, time, commands or workflow run, affected systems, and result. It should notify the second engineer and fractional CTO immediately. The CTO then compares the action with logs, verifies that ordinary controls were restored, and records approval or a finding.

Set a review deadline that your team can meet, such as the next business day, and test the process before an incident. A sealed credential nobody can retrieve is not a recovery control. A shared password in a chat channel is not controlled access.

Do not let retrospective approval erase the exception. Keep it in an exception register and look for patterns. Repeated break-glass releases may show that the normal approval window is unrealistic, the deployment system is unreliable, or engineers retain too little routine access to operate the service.

SOC 2 Type II fieldwork examines operation over time, so one unreviewed exception can become a control deviation. Whether it affects the report depends on the control wording, frequency, population, circumstances, and auditor's evaluation. Tell the auditor about the designed exception before the period, and report actual deviations promptly rather than hoping a sample misses them.

The fractional CTO also needs coverage. Name an alternate approver for absences, define the alternate's qualifications and permissions, and include that person's access in reviews. If the company has no suitable alternate, narrow the CTO-dependent gate to changes that can wait and rely on a logged emergency path for the rest.

Know when two engineers are no longer enough

The design stops fitting when the team cannot maintain independent decisions, timely operation, and credible review for the in-scope risks. Headcount alone does not set that boundary. Change volume, customer commitments, system sensitivity, time zones, and concentration of privileged knowledge do.

Watch for concrete signals: peer approvals become automatic, the CTO reviews large populations long after the fact, emergency bypasses become routine, one engineer owns an unreviewable subsystem, access removals wait for the next meeting, or the same administrator can disable controls and edit retained logs. Those conditions call for a different operating model.

The next addition does not always need to be another developer. A release engineer can own delivery controls. A security or platform engineer can separate identity and logging administration. A managed provider can monitor protected logs. An external reviewer can perform periodic technical access checks. Choose the role that removes the largest unresolved conflict.

Before the SOC 2 observation period, run a tabletop with Engineer A as change author, Engineer B unavailable, and the CTO outside working hours. Trace a routine release, a sensitive release, a privileged access request, and an emergency rollback. Every action should have an authorized actor, enforced path, retained record, and alternate.

I use this same control-to-evidence test in a Team & AI Audit: identify who can make each risky decision, inspect what the tools enforce, and price the smallest change that closes the gap. The useful outcome is not a prettier responsibility chart. It is a delivery system in which two engineers can move fast without asking an auditor to trust invisible role changes.

Frequently Asked Questions

Does SOC 2 require separate employees for development and deployment?

No. The Trust Services Criteria define control objectives, not a minimum staffing model. You must show that conflicting authority is prevented or independently detected through people, permissions, workflows, and retained evidence.

Can one engineer deploy code written by the other engineer?

Yes, if the code received independent approval and the deployment uses the approved artifact through a controlled pipeline. The deployer should not be able to replace the artifact, alter the workflow unnoticed, or erase the record.

Can two engineers review each other's pull requests for SOC 2?

Yes, peer review can cover routine changes when the repository blocks self-approval, direct pushes, and administrator bypass. Sensitive paths and exceptions should receive another qualified approval, such as the fractional CTO's.

What should a fractional CTO approve for SOC 2?

The fractional CTO should own the duty matrix, approve sensitive changes and privileged access, review access populations, and close exceptions. Approving every small change wastes time and trains the team to treat approval as ceremony.

Who reviews the fractional CTO's own access?

A founder, CEO, or other authorized executive should review the business need for the CTO's access. If technical judgment is missing internally, an external security adviser can assess the permission level, but the CTO still cannot approve their own access.

Is a CI/CD service account a separate person for separation of duties?

No. A service identity can separate execution from human authorization, but it cannot supply independent judgment. Its value comes from narrow permissions, repeatable behavior, and records tied to an approved artifact.

How often should a two-person team review access?

Set the frequency from the risk of each system and account class, then follow it consistently. Privileged production access often deserves a shorter interval than low-risk application access, but SOC 2 does not impose one universal quarterly rule.

What evidence proves separation of duties during a SOC 2 audit?

Keep live rule exports, pull request approvals, check results, artifact identifiers, deployment events, raw account exports, review decisions, and remediation records. Reconcile each evidence population to a system source instead of handing the auditor a list recreated from memory.

Can an engineer bypass approval during a production outage?

A documented break-glass path can permit that when customer impact or security risk requires immediate action. It should log the actor and action, alert an independent reviewer, limit the repair, and require retrospective review within a stated period.

When does a two-engineer SOC 2 model stop working?

It stops working when reviews become automatic, exceptions become routine, one person controls an unreviewable subsystem, or administrators can alter both production and its only logs. Add the role that removes the largest conflict, which may be security, platform, release, or external review rather than another application developer.

Related Posts