I build data pipelines, security detections, and the Linux, database and network infrastructure underneath them.
I spent two and a half years in York University's campus security control room, including as a shift lead. That work meant triaging physical access alarms, coordinating emergency responses and training operators. The technical projects below show what I build and how I test it.
Twenty business questions on a decade of Toronto police data, one SQL query each, using window functions, CTEs, quantiles and z-score anomalies. Findings are written up and published as a live dashboard.
452,949 City of Toronto incident rows, 2014–2025 · auto theft rose 243% from 2017 to 2023, then fell 23% in 2024
Evidence · 22 Sep 2026 data snapshot
Twenty reproducible SQL questions, generated result tables and four charts sit behind the dashboard.
A Kubernetes platform run entirely from Git. Terraform installs Argo CD; Argo CD installs Kyverno admission policies, Prometheus, Grafana and Alertmanager, Argo Rollouts, and the app. New versions ship as a 25% canary and roll back on their own if Prometheus shows errors.
Admits only images signed by my pipeline · CI rebuilds a 3-node cluster and runs the full end-to-end suite on every push
Tested in CI on every push
Terraform bootstrapArgo CD syncKyverno admissionCanary + rollback
Unsigned images and images signed by a different workflow are both rejected. A bad release fires an alert, fails its canary analysis and is rolled back without touching the stable pods. EKS and AKS Terraform modules are tested against mocked providers, not yet deployed.
Pulls police incidents, TTC delays and census data from the City's CKAN API into PostgreSQL, models it into a star schema with dbt, and schedules it with Airflow. A delay model retrains after each run and is served through FastAPI.
909,698 rows across four raw tables · ~5 s load stage, ~40 s end to end on a laptop · 40 dbt tests passed
Run summary · 22 Sep 2026
City open dataPostgreSQL11 dbt models40 passed / 0 failed
The hourly delay model is a prototype; its evaluation did not beat the simpler historical-rate baseline.
A primary, a streaming replica and a WAL archive, with everyday DBA work done against them: health diagnostics, index tuning measured before and after, a point-in-time recovery drill that brings back a dropped table, and a failover drill. Runbooks included.
Eleven Sigma rules covering an intrusion from initial access to defence evasion. CI converts and tests their SQL against planted events and near-misses; SPL and supported KQL outputs are generated with pySigma.
Five security gates run before anything is built: Gitleaks, Semgrep, Trivy, Checkov and an image scan. Images that pass are signed keylessly with cosign, get an SPDX SBOM attestation and SLSA build provenance, and are promoted by digest to the GitOps platform.
4 demo pull requests, each blocked by the right gate · 35 MB runtime image with 0 known CVEs
Evidence · closed demo pull requests
A critical CVE, a hard-coded key, eval() on user input and a root container were each stopped before a build. Building them exposed a Semgrep ruleset gap and a Gitleaks false positive, both fixed.
Eight Ansible roles that provision and harden Ubuntu servers: users and sudo, SSH, ufw, LVM storage, NFS, auditd, patching and monitoring. Checked two ways: a second run changes nothing, and the hosts pass CIS Benchmark items.
41/41 selected hardening checks on two Ubuntu lab hosts · second run changed=0
The monthly review a SOC lead asks for, written in SQL over 45,839 Wazuh alerts: noisy-rule tuning, time-to-triage by severity, ATT&CK coverage gaps, and a query that rebuilds a lateral-movement chain from raw alerts. An Isolation Forest flags hosts acting unlike their own baseline.
3 rules made up 42% of alerts with under 1% true positives
Six FRRouting routers in Docker: an OSPF backbone, an iBGP full mesh, and dual-homed eBGP to two ISPs with route policy. Every router config, and the lab itself, is generated from one YAML file with Jinja2.
22 tests boot the whole network in CI on every push
The same pipeline rebuilt on Azure. Data Factory lands raw files in ADLS Gen2, Databricks builds bronze, silver and gold Delta tables, and Synapse serverless serves them to Power BI. Defined in both Bicep and Terraform, with managed identities everywhere and storage keys and SQL passwords disabled.
Notebooks verified on Spark; row counts match the dbt build exactly · porting to Terraform exposed and fixed three security gaps
Eight hours of generated office traffic with three planted threats, run through Zeek and hunted in SQL: command-and-control beaconing by timing regularity, DGA domains by DNS entropy, and exfiltration by byte asymmetry.
424K packets · each planted threat ranked #1 in its hunt
An Active Directory domain on Samba AD (Kerberos, LDAP, DNS, SYSVOL) with OUs, groups, a password policy, a linked GPO and a Linux client joined through winbind. Scripts handle onboarding, offboarding and audit reports.
30/30 end-to-end checks, including real Kerberos logins
A credit default model on 30,000 customers in Spark MLlib, with the full MLflow lifecycle: tracked runs, cross-validated tuning, a registered model behind a @champion alias, and a batch job that scores by alias instead of by file.
Trivy scans of ten container images, enriched with CISA's Known Exploited Vulnerabilities list and EPSS scores, then ranked in SQL into a tiered queue a team can work through, instead of a list sorted by CVSS.
3,934 findings across ten container images → 95 fixable P0/P1 priorities using KEV and EPSS
CloudTrail, GuardDuty and AWS Config feed EventBridge. A Lambda closes public S3 buckets, world-open security groups and compromised access keys, and alerts on everything else. Deployed with Terraform.
Streams live TTC vehicle positions from the GTFS-Realtime feed through Redpanda (Kafka API) into PostgreSQL. The sink is idempotent, so restarts and replays never double-count a position.
~1,450 vehicles every 20 s · 13,673 rows in a 12-minute run
Connected BigQuery to data in S3, queried an external table and exported results back to S3. The repo reconstructs the IAM policy and SQL as reusable templates.
Reconstructed from the original walkthrough; no live cloud deployment in this repo.
Migrated an EC2 instance with replication, a test clone and cutover. The repo preserves the original screenshots and adds a practical migration runbook.
Historical project; the original VM and cloud configuration were not preserved.
Explored a public cardiovascular dataset, trained an AutoGluon classifier and evaluated predictions with a confusion matrix. The repo reconstructs the training script.
Learning exercise only; no clinical validation or diagnostic use.
My York University roles were in campus physical security: CCTV, door access, alarms and emergency dispatch. That work sharpened my incident triage, escalation and shift leadership skills.
Mar 2023 – Jan 2025
Security Operations Centre Team Lead
York University, Toronto
Led a shift of control room operators monitoring CCTV, access control and alarm systems across the Keele and Glendon campuses, around the clock. Decided when to dispatch security or call police, fire or EMS, reviewed every operator's incident reports, wrote the reports for serious incidents, and trained new operators.
Jul 2022 – Mar 2023
Security Control Room Operator
York University, Toronto
Monitored live CCTV, door access alerts and alarm panels, handled emergency and non-emergency calls, and pulled footage and access records for investigations.
Sep 2021 – 2022
Floor Manager
Larry the Liquidator, Scarborough
Ran daily store operations: opening and closing, cash reconciliation, inventory and staff supervision.
Education
Computer Science
York University, Toronto
Certifications
CompTIA Security+
AWS DevOps Engineer – Professional
Microsoft Power Platform Developer Associate
Google Cybersecurity Professional Certificate
Skills
Data
SQL, Python, PostgreSQL, dbt, Airflow, PySpark, Databricks, Kafka, DuckDB, Power BI
I also run a small web design studio for local businesses in Toronto. I handle the whole job: talking to the client, planning the pages, building, hosting, and teaching staff to update the site themselves.