Security Awareness Engineering

Production engineering guide for security awareness engineering covering patterns, implementation strategies, and operational best practices.

Security Awareness Engineering

Security Awareness Engineering is the practice of embedding security‑checkable signals into the tools, files, and workflows engineers use every day, so that risk detection happens before code reaches production. It matters when every commit triggers a pipeline, infrastructure is defined in declarative files, and operators need to confirm that security policies were not silently skipped. This page is not about training programs or compliance checklists; it is about concrete mechanisms you can write, run, and audit.

1. Hunt for hardcoded credentials in git history

Goal: Detect passwords, tokens, or secret strings that accidentally landed in a repository.

The most direct way with standard tooling is to search commit messages and diffs. Run:

git log --all --oneline --grep='password|secret|token'

This returns every commit whose message contains one of those terms. To scan the actual changes staged for the next commit:

git diff --cached | grep -iE 'password\s*=\s*\S+|secret\s*=\s*\S+|token\s*=\s*\S+'

If you prefer a working‑tree scan (any file in the current checkout), git grep is built‑in:

git grep -r 'password=' .

Sharp edge: git grep only searches the checked‑out tree. Secrets added in earlier commits require git log -p --all or git rev-list --all | xargs git grep -iE 'password='. A common blind spot is base‑64‑encoded or URL‑encoded values that don’t match a literal password= string; those need entropy‑based scanners or dedicated tools like git‑secrets (invoked as git secrets --scan --cached), which returns exit code 1 and prints each matched pattern when a secret is found.

2. Validate pod security defaults before applying manifests

Goal: Confirm that a Kubernetes manifest does not inherit wide‑open runtime defaults.

The orchestrator’s API documents the expected schema. Use kubectl explain to inspect a single field:

kubectl explain pods.spec.containers[0].securityContext

Typical output lists the valid sub‑fields: allowPrivilegeEscalation, capabilities, privileged, readOnlyRootFilesystem, runAsGroup, runAsNonRoot, runAsUser. If the YAML omits securityContext entirely, the kubelet applies cluster‑wide defaults—often runAsUser: 0, runAsGroup: 0, and privileged: true unless a default PodSecurityPolicy or BuiltInSecurityPolicy is in place that overrides them.

Concrete check: Write a small YAML snippet that explicitly sets runAsNonRoot: true and readOnlyRootFilesystem: true. Re‑run the kubectl explain command; the now‑present fields will be validated against the schema, and kubectl apply will fail if any sub‑field is miss‑spelled or set to an unsupported value.

Sharp edge: kubectl explain validates against the open‑API schema of the control plane, but it does not guarantee that an admission webhook or runtime policy will enforce the same constraints. A manifest may pass schema validation and still be rejected by a mutating webhook, or conversely, be accepted with silently escalated privileges if the webhook is mis‑configured. Always pair schema checks with kubectl auth can-i or a dry‑run (kubectl apply --dry-run=client -o yaml) to observe the exact object that will be sent to the API server.

3. Probe HTTP security headers of a service

Goal: Verify that a deployed service enforces HTTPS, content‑type policing, and HSTS.

curl can fetch raw response headers in a single command:

curl -I https://api.example.com 2>&1

The output begins with the HTTP status line and then lists each header on its own line. Look for:

If any of these are absent, the service defaults to a less‑restrictive posture. To extract a single value programmatically:

curl -I https://api.example.com 2>&1 | grep -i 'strict-transport-security'

Sharp edge: curl -I only returns headers for the initial response. Redirects (301/302) may be followed automatically by some curl versions or suppressed with -L, which changes which headers appear. Middleware, load‑balancers, or API gateways can strip or add headers after the front‑end server, so a header present in the curl output may not exist in the response seen by the client after the full proxy chain. For a complete picture, instrument the application layer or use a TLS‑terminating proxy’s diagnostic endpoint.

4. Check system‑service hardening status

Goal: Confirm that the SSH daemon respects protocol‑level hardening and root‑login policy.

systemctl can query individual unit properties without opening an editor:

systemctl show sshd -p PermitRootLogin -p Protocol

PermitRootLogin accepts yes, no, prohibit‑password, or forced‑command. Protocol lists the allowed SSH versions (typically 2, and sometimes 2,1 on legacy systems). A typical hardened output might show PermitRootLogin no and Protocol 2.

Sharp edge: systemctl show reads the unit file that systemd loaded at boot. If a drop‑in snippet in /etc/systemd/system/sshd.service.d/ overrides a setting, the show output still reflects the base unit unless you append --no-blocks or explicitly check the drop‑in path with systemctl cat sshd. Runtime changes made via sshd -t or runtime configuration (e.g., via setsid) are not persisted across restarts unless the unit file is updated.

5. List PostgreSQL user roles and their inherited privileges

Goal: Audit which roles can log in and what privileges they inherit.

psql provides a built‑in meta‑command that formats the role catalogue:

psql -c "\du"

The output columns include Role name, Attributes, and Members. Key attributes to watch for: SUPERUSER, INHERIT, CREATEROLE, CREATEDB, LOGIN. A role without LOGIN cannot be used to establish a connection, even if it appears in the list.

Sharp edge: \du shows the role definition as it exists in the catalog, but it does not reflect runtime session state. A role’s effective privileges can change via GRANT/REVOKE between psql invocations, and DEFAULT PRIVILEGES schema‑level grants may not appear in the top‑level listing. For a complete picture, cross‑reference \du with SELECT * FROM pg_roles WHERE rolcanlogin; and inspect pg_authid for the rolcanlogin flag directly.

Sharp edges – what silently fails, which options are confused, what you only learn after it breaks in production

This page was rewritten on 17 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.