I build and maintain web systems, from design through to production.
I’m Rain, a third-year computer science student at SFU. In the past year I’ve built and run production systems for a security-key company and a property management firm, mostly in Python, TypeScript and Rust.
Experience
- Aug 2026 – Present
MNT Realty · Vancouver, BC, Canada
The only engineer at a property and strata management company. I build and run the internal systems the office works from, and connect them to the company’s Microsoft 365 accounts and data.
Work- Designed and built MNT Control Center, an internal platform that replaces the separate tools the office used before.
- Set up organisation sign-in and role-based access with Microsoft Entra ID, the Graph API and OAuth 2.0.
- Built the internal web applications behind it in Next.js, Node.js and PostgreSQL.
- Automated recurring office work: sorting incoming email, looking up owner records, and an internal assistant that answers staff questions from company documents.
Operations- Run hosting, deployment, domains and DNS, and the release workflow on Vercel and GitHub Actions.
- Write the tests and the documentation myself, so the systems can be handed over later.
TechnologiesPythonTypeScriptNext.jsReactNode.jsTailwind CSSPostgreSQLMicrosoft 365Microsoft Entra IDMicrosoft Graph APIOAuth 2.0DockerVercelGitHub ActionsRelated work - Sep – Dec 2025
FEITIAN Technologies · International Department · Beijing, China
Built three systems for FEITIAN’s post-quantum FIDO2 work and ran them end to end: a public WebAuthn developer platform, a software security key in Rust, and a customer demo site.
Work- Built the company’s first WebAuthn/FIDO2 developer platform: one place to register, sign in, inspect and debug credentials, in place of the third-party tools the team had been using.
- Wrote a CTAP2 authenticator in Rust that Linux presents as a virtual USB security key, so browsers and libfido2 could test ML-DSA credentials before hardware existed.
- Built a self-service demo site so customers could try passwordless sign-in and security keys without going through support.
Delivery- Deployed with Docker on Linux servers and Google Cloud Run, with GitHub Actions running the tests, the builds and a daily FIDO metadata refresh.
- Worked with FEITIAN’s hardware and security engineers so the tools matched the real devices and the data they returned.
- The internship ended in December; I still maintain all three.
TechnologiesPythonFlaskJavaScriptHTMLRustTypeScriptReactTailwind CSSDockerGoogle CloudGitHub ActionsWebAuthn / FIDO2CTAP2.1ML-DSAliboqsRelated work
Selected Work
- Aug 2026 – Present
One Next.js application serving three sites for a property management company: a public website, an owner portal for residents, and an admin console for staff.
Next.jsTypeScriptReactmntrealty.vercel.appWhat it isThe system MNT Realty runs on. Prospective clients see the public website. Residents of the stratas MNT manages sign in to the owner portal to read notices, book amenities and download documents. Staff run all of it from the admin console.
How it worksThree sites, three subdomains, one build. A proxy routes each subdomain to its own pages — admin to the console, owners to the portal — and the public site answers those same paths with a not-found page. Each keeps its own layout and its own host-only session cookie. Public pages are prerendered; the console and the portal render per request. Every read and write goes through one store interface, so what staff enter reaches residents at once and the store behind it can be swapped for the drafted PostgreSQL schema without touching a screen.
Technical challengesAccess is defined once, in a table that the navigation, the page guards and the file route all read. A section outside your role returns not-found rather than forbidden, so the portal never reveals what another role can see. Each strata is a hard boundary: while one is open, nothing from another is reachable. MNT’s own business facts — company details, the strata-document fee schedule, the amenity slot template — are versioned data an administrator edits under Settings rather than values in the source, with every saved version restorable.
StackNext.jsReactTypeScriptTailwind CSSNode.jsPostgreSQLVitestVercelGitHub ActionsStatusAll three are built and deployed; cloud data and backend workflows are next. The source belongs to MNT Realty and is not public.
- Sep 2025 – Present
A public tool for testing FIDO2/WebAuthn flows, including post-quantum ML-DSA credentials.
What it isA Flask web app for developers building on FIDO2. Register and sign in with real or virtual authenticators, edit the raw WebAuthn request as JSON, decode what comes back, and look up any authenticator in the FIDO Alliance metadata service. Built during my internship at FEITIAN, and I still maintain it.
How it worksFour tabs: simple sign-in, an advanced mode with an editable request, a codec for attestation objects and CBOR/CTAP structures, and a metadata explorer with root-certificate checks. The server is a modified copy of Yubico’s python-fido2 with ML-DSA-44, -65 and -87 added through liboqs. Each visitor gets an isolated session store, on local disk or Google Cloud Storage, cleaned up after 14 days of inactivity.
Technical challengespython-fido2 had no post-quantum support, so I added the COSE identifiers, the key handling and the attestation checks for ML-DSA without disturbing the classical paths. Shipping liboqs in the image made Cloud Run slow to start, which led to a lazy warm-up and a one-worker gunicorn build. The FIDO metadata goes stale, so a daily GitHub Action re-verifies the snapshot and commits it — nobody has to remember.
StackPythonFlaskJavaScriptDockerGoogle CloudGitHub Actionspython-fido2liboqsJinjapytestVitestStatusLive at webauthnlab.tech and maintained under FeitianTech. About 120 server test files, plus frontend and post-quantum tests, run in CI.
- Nov – Dec 2025
A customer-facing site for trying FEITIAN’s passwordless and post-quantum sign-in.
ReactPythondemo.ftsafe.comWhat it isA demo for FEITIAN’s customers and sales team. The developer platform is built for engineers; this one is for people evaluating the products. Register a security key, sign in, and watch a post-quantum credential work, without reading a specification.
How it worksA React front end over the same authentication service and ML-DSA support as the developer platform, with a guided interface in place of raw requests and responses.
StackReactJavaScriptPythonFlaskWebAuthn / FIDO2ML-DSAliboqsStatusLive at demo.ftsafe.com. The source belongs to FEITIAN and is not public.
- Oct – Nov 2025
A CTAP2 security key in software. Linux presents it as a USB device, so browsers can test post-quantum credentials without hardware.
RustLinuxRepositoryWhat it isA Rust workspace that behaves like a FIDO2 security key, in software. FEITIAN’s engineers and partners needed to develop against ML-DSA credentials before the hardware was ready. It started as my own repository and is now maintained under FeitianTech.
How it worksAn authenticator core implements CTAP2.1 on the Trussed framework with littlefs2 storage: credential management, PIN/UV protocols 1 and 2, and reset. A runner registers a virtual USB HID device through Linux uhid and speaks CTAPHID, so Chrome, Firefox and libfido2 see an ordinary key. It advertises ES256 and ML-DSA-44, -65 and -87, and ships a small command-line tool (attach, detach, status, reset, pin) that can run as a daemon.
Technical challengesBrowsers are strict about what they will talk to, so the HID transport and the CTAP state machine had to be exact before Chrome or Firefox accepted the device. CTAP and COSE structures were designed around classical keys, and post-quantum ones do not fit them neatly. The first version called liboqs over a C FFI; it later moved to the pure-Rust fips204 crate, with secret keys zeroised on drop.
StackRustLinux UHIDTrussedlittlefs2CTAP2.1fips204liboqsclapStatusWorks on Linux and is used alongside the developer platform. CI runs rustfmt, clippy and the test suite.
Other Work
- Feb 2025 – Present
A statically generated portfolio in English and Japanese, built on one small design system shared with my resume and cover letter.
What it isMy portfolio, at rainzhang.me. One scrolling page in two languages, on its own small design system: one typeface, ivory paper, one accent colour, no borders or shadows. My resume and cover letter use the same system, so the three read as one piece of work.
How it worksNext.js App Router prerenders both languages at build time from one typed content model, so /en and /ja stay structurally identical and only the prose differs. Tailwind reads the design system’s tokens rather than raw values, Albert Sans is self-hosted through next/font, and middleware sends a first-time visitor in Japan to the Japanese route unless they have chosen otherwise.
FeaturesExperience and project rows expand in place, a language switch whose pill slides between English and Japanese, a first-screen entrance in pure CSS, a contact form that posts to Formspree behind a honeypot and a request timeout, and a copy-to-clipboard email. Everything renders without JavaScript and every duration honours prefers-reduced-motion.
StackNext.jsTypeScriptReactTailwind CSSPlaywrightVitestVercelGitHub ActionsStatusLive at rainzhang.me. Unit tests in Vitest and an end-to-end suite in Playwright across Chromium, Firefox, Safari and mobile run in CI.
- Jan – Apr 2025
A course project with three classmates: a trip planner that picks a destination from your passport and visas, then fills in hotels, restaurants and an itinerary.
What it isA CMPT 276 group project. You answer a short questionnaire or pick a place, choose dates, and get hotels, restaurants, attractions and a day-by-day plan, with a chat assistant for follow-up questions.
My partI built the React and Tailwind front end, the passport and visa questionnaire that asks OpenAI for a destination, the date steps and their validation, and the chat widget. A teammate wrote the Express service that fronts the Tripadvisor API.
Looking backThe OpenAI key is called from the browser. Today I would put it behind the backend.
StackReactJavaScriptTailwind CSSViteOpenAI APITripadvisor APICypressVercelStatusFinished in April 2025 and still live.
Background
Simon Fraser University
BSc, Computer Science · Vancouver, BC, Canada · Graduating April 2027
CGPA 3.44 / 4.33. Dean’s Honour Roll in Fall 2024 and Summer 2025.
Contact
If you’re hiring, or want to talk about any of this, please write to me.
- linkedin.com/in/rainzhang05
- GitHub
- github.com/rainzhang05