Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Kubernetes Security: ServiceAccounts, RBAC, Pod Security Standards, securityContext and NetworkPolicy
Give every app its own ServiceAccount, don't mount the token unless needed, protect the namespace with restricted Pod Security Standards, and after a default deny NetworkPolicy open only the paths you need. With real kind output we test RBAC with kubectl auth can-i, catch the aspnet:10.0 image running as root, see what readOnlyRootFilesystem does to .NET Data Protection, try user namespaces and hit a default deny that forgot DNS.
Jenkins Credentials: withCredentials, Credentials Binding and the Groovy String Interpolation Trap
You expose a secret in the narrowest scope with credentials() or withCredentials and read it in sh as a shell variable inside single quotes; Groovy interpolation with double quotes leaks it to the process. Credential types and SYSTEM/GLOBAL/folder scopes, readFile in JCasC, masking that catches base64 but misses a fragment, sshagent, team isolation with folder credentials and external secret stores.
Installing Jenkins: LTS with Docker, Java 21, the First Admin and Choosing Plugins
You install Jenkins in Docker with a version-pinned LTS image, a named JENKINS_HOME volume and Java 21, and you skip the setup wizard with plugins.txt and JCasC. The anonymous volume trap, initialAdminPassword, the Docker-in-Docker TLS certificate error, anonymous access, zero executors on the controller, the CSRF crumb, agent-to-controller security and installing from the Linux package.
HTTPS, Security Headers, Rate Limiting and Load Balancing in Nginx
With real runs: TLS termination in Nginx, HTTP/3 with http2 on and listen quic, security headers that don't disappear thanks to add_header_inherit merge, HSTS from a single place, 429s with limit_req, and round robin spreading unevenly without an upstream zone. ip_hash, the sticky cookie that came with 1.29.6 and passive health checks with max_fails: when an instance dies the client sees no error, but non-idempotent requests and unhealthy yet running processes need separate handling.
ASP.NET Core Behind a Reverse Proxy: Forwarded Headers, KnownIPNetworks and the Real Client IP
An app behind a proxy sees the client's IP and HTTPS only if UseForwardedHeaders is set up correctly: you must say which headers to process and add the proxy's address to KnownProxies or, on .NET 10, KnownIPNetworks. With real runs we look at the HTTPS redirection loop, the ASPDEPR005 warning, fake X-Forwarded-For values and ForwardLimit, PathBase via X-Forwarded-Prefix and Data Protection keys across multiple instances.
GitHub Actions Security: SHA Pinning, Lockfiles, pull_request_target and Preventing Script Injection
Pin actions to full commit SHAs and keep them current with Dependabot and lockfiles, pass untrusted values through env: instead of run:, and never run PR code in pull_request_target. The tj-actions case, zizmor and actionlint findings, gh actions-lock, real script injection output under act, checkout@v7 and the December 2, 2026 change, a safe workflow_run pattern and read-only cache tokens.
Secrets, Variables and GITHUB_TOKEN Permissions in GitHub Actions
Secrets are defined at organization, repository and environment level, the narrowest level wins, and they are masked in logs by text matching; derived values such as base64 and fields read out of JSON are not masked. With fake secrets in act we show ::add-mask::, secrets in if conditions, variables and an empty GITHUB_TOKEN, and cover least privilege with permissions, the vulnerability-alerts scope from September 2026, and GitHub App tokens instead of PATs.
Pipeline Security and Secrets: Least Privilege, Short-Lived Credentials and Supply Chain
The pipeline is the most powerful user, holding production keys; keeping secrets in a store, least privilege per job, short-lived tokens via OIDC instead of long-lived cloud keys and pinning actions to commit SHAs close most of the risk. Real act output showing a base64-encoded secret escaping masking, script injection caught by actionlint, fork PR risks, and a short look at SLSA v1.2 and SBOMs.