PS Product SecurityKnowledge Base

๐Ÿ’ป Developer Workstation Hardening for AppSec and DevSecOps

Intro: A developer workstation is not just a laptop. It is an execution environment for code, containers, secrets, package managers, browser sessions, cloud CLIs, and signing keys. For Product Security, a compromised workstation can become source-code theft, secret leakage, poisoned artifacts, or trusted-signature abuse.

What this page includes

  • secure baseline for VS Code and JetBrains users;
  • pre-commit bundles for local guardrails;
  • local Docker security, including rootless mode and safer defaults;
  • commit signing, Cosign, and key hygiene;
  • secrets hygiene and safe sandboxing patterns for labs, PoCs, and untrusted code.

The workstation threat model

A developer workstation typically has:

  • access to source code and design notes;
  • cloud CLIs and cached tokens;
  • package registries and build tools;
  • local containers and virtual machines;
  • browser sessions into GitHub, GitLab, Jira, cloud consoles, and secrets systems;
  • signing keys or the ability to request signatures.

That means one compromised workstation can affect:

  • confidentiality of code and secrets;
  • integrity of commits, tags, and release artifacts;
  • trust in CI/CD and production deploys.

1. Separate trust zones on the same machine

Use at least two categories of environments:

  • daily engineering zone โ€” your normal editor, browser, and tools;
  • unsafe or experimental zone โ€” disposable VM, dev container, or remote sandbox for PoCs, unknown scripts, and exploit labs.

Do not run unfamiliar shell scripts, offensive labs, or unknown Docker images in the same environment where your long-lived cloud tokens and signing material live.

2. Prefer passkeys or phishing-resistant MFA for key portals

High-value portals include:

  • GitHub / GitLab;
  • cloud consoles;
  • password managers;
  • artifact registries;
  • CI/CD admin portals;
  • SSO / IdP admin interfaces.

3. Keep local admin privileges limited

The more your workstation is operated as permanent local admin/root, the easier it is for malicious scripts or poisoned packages to pivot into lasting host compromise.

VS Code setup

  • Semgrep extension for fast inline finding feedback;
  • YAML / Docker / Terraform extensions only from trusted publishers;
  • avoid random marketplace extensions that request broad workspace access without justification.

Semgrepโ€™s official VS Code extension supports scanning as you open and change files, showing inline results and autofix where rules provide it. ๎ˆ€cite๎ˆ‚turn359551search2๎ˆ

{
  "security.workspace.trust.enabled": true,
  "extensions.autoCheckUpdates": true,
  "extensions.autoUpdate": true,
  "git.enableCommitSigning": true,
  "files.autoSave": "off",
  "terminal.integrated.confirmOnExit": "always"
}

Practical comments

  • keep Workspace Trust enabled, especially when opening unfamiliar repos or extracted conference/demo material;
  • do not install one-off extensions from random blog posts for parsing IaC or security files unless the publisher is trusted;
  • prefer dev containers or a disposable VM when opening complex PoCs that include helper scripts.

JetBrains setup

JetBrains IDEs are strong for teams that want connected VCS hygiene and built-in Git/GPG integration.

JetBrains documents current GPG commit signing under Settings / Preferences โ†’ Version Control โ†’ Git โ†’ Configure GPG Key. The 2025.3 docs explicitly recommend using a proper gpg2 setup with working pinentry support. ๎ˆ€cite๎ˆ‚turn838320search0๎ˆ

JetBrains baseline

  • enable commit signing;
  • use trusted plugins only;
  • review IDE HTTP client environment files and run configurations for secrets;
  • avoid storing persistent credentials in run configurations checked into the repo.

Pre-commit bundle

Use a local pre-commit stack to catch the easiest issues before they ever reach CI.

  • gitleaks or git-secrets for secrets;
  • semgrep for fast code and config checks;
  • formatting / linting hooks for YAML, JSON, Dockerfiles, and shell where relevant.

Example .pre-commit-config.yaml

repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.24.2
    hooks:
      - id: gitleaks

  - repo: https://github.com/returntocorp/semgrep
    rev: v1.120.0
    hooks:
      - id: semgrep
        args:
          - --config=p/owasp-top-ten
          - --config=p/secrets
          - --config=p/terraform

  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v5.0.0
    hooks:
      - id: check-yaml
      - id: end-of-file-fixer
      - id: trailing-whitespace

Install

python3 -m pip install --user pre-commit
pre-commit install
pre-commit run --all-files

Git signing

Why sign commits

Commit signing does not prove code is safe, but it improves provenance and makes repo history harder to tamper with silently.

GitHub supports GPG, SSH, and S/MIME commit signature verification. The docs explicitly note that for most individual users, GPG or SSH are the most practical choices, and that SSH signing requires Git 2.34 or later. ๎ˆ€cite๎ˆ‚turn838320search1๎ˆ‚turn838320search5๎ˆ

For many teams, SSH commit signing is now simpler than GPG for daily commits. Keep GPG for teams with existing smartcard/YubiKey workflows or policy requirements.

Example SSH signing setup

ssh-keygen -t ed25519 -C "dev-signing@example.com" -f ~/.ssh/id_ed25519_signing

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519_signing.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true

Then upload the public signing key to your Git hosting provider as a signing key, not only as an auth key.

Example GPG signing setup

gpg --full-generate-key
gpg --list-secret-keys --keyid-format=long

git config --global user.signingkey <LONG_KEY_ID>
git config --global commit.gpgsign true
git config --global tag.gpgsign true

Cosign on the workstation

Why Cosign belongs on developer workstations

Cosign is not only for CI. It is useful locally for:

  • verifying the provenance of security tools you download;
  • verifying signed container images;
  • testing blob signing and verification before CI rollout;
  • debugging attestation flows.

Sigstoreโ€™s current docs still position Cosign as the recommended CLI for signing and verifying software artifacts. Installation options include go install, Homebrew, distro packages, GitHub Actions, GitLab, and container images. ๎ˆ€cite๎ˆ‚turn359551search1๎ˆ‚turn359551search4๎ˆ

Install Cosign

# Homebrew / Linuxbrew
brew install cosign

# or Go
GO111MODULE=on go install github.com/sigstore/cosign/v3/cmd/cosign@latest

Verify a blob locally

cosign sign-blob artifact.tar.gz --bundle artifact.sigstore.json
cosign verify-blob artifact.tar.gz --bundle artifact.sigstore.json \
  --certificate-identity-regexp '.*' \
  --certificate-oidc-issuer https://oauth2.sigstore.dev/auth

Local Docker security

  • prefer rootless Docker where compatible;
  • avoid mounting /var/run/docker.sock into random containers;
  • avoid --privileged unless you have a short-lived, explicit reason;
  • do not treat local third-party images as trusted code;
  • prune old images and build cache regularly.

Dockerโ€™s current docs say rootless mode runs both the daemon and containers inside a user namespace, unlike userns-remap, where the daemon still runs as root. ๎ˆ€cite๎ˆ‚turn359551search0๎ˆ

Rootless Docker quick setup

# prerequisites vary by distro; uidmap is typically required
sudo apt-get install -y uidmap

dockerd-rootless-setuptool.sh install
systemctl --user start docker
systemctl --user enable docker

Verify user namespace mapping

docker run --rm alpine cat /proc/self/uid_map

Safer defaults when testing images

docker run --rm -it \
  --read-only \
  --tmpfs /tmp:size=64m,noexec,nosuid \
  --cap-drop=ALL \
  --security-opt no-new-privileges \
  alpine:3.20 sh

Secrets hygiene

Principles

  • do not store secrets in shell history, repo files, IDE run configs, or screenshots;
  • prefer federated auth and short-lived credentials over long-lived static keys;
  • separate human access from automation identities;
  • rotate local cloud credentials and delete stale CLI profiles.

Fast local checks

gitleaks dir .
git secrets --scan-history

Common workstation leak points

  • .env files committed accidentally;
  • cloud CLIs leaving cached tokens in home directories;
  • IDE database/browser connectors with saved passwords;
  • copied kubeconfigs shared over chat or left in screenshots;
  • shell history with export AWS_SECRET_ACCESS_KEY=....

Safe sandboxing for labs and PoCs

Good options

  • disposable VM for malware-ish or offensive material;
  • dev container for ordinary untrusted build/test content;
  • remote throwaway cloud account or isolated lab for cloud exploitation exercises;
  • separate browser profile for conference tools, demos, and disposable SaaS signups.

Bad option

Running random PoC code in the same host session where you:

  • are logged into GitHub/GitLab;
  • have AWS/GCP/Azure CLI tokens cached;
  • have ~/.kube/config for production clusters;
  • can sign commits or images.

Suggested workstation checklist

  • full-disk encryption enabled
  • phishing-resistant MFA for code, cloud, and SSO portals
  • trusted password manager in use
  • commit signing enabled
  • Semgrep and secret scanning available locally
  • pre-commit hooks installed in high-value repos
  • Docker rootless or otherwise reduced-privilege local runtime considered
  • separate sandbox for labs, PoCs, and suspicious repos
  • stale cloud credentials and kubeconfigs reviewed regularly

Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.