This is a simple app to help me find my favourite korean restaurants. I live in Korea and I like to eat great food! This app will help me not to get hungry!
View it live here: https://korean-restaurants-x1ncq0w8e0jnm.cpln.app/ (Hosted on Control Plane). Apologies, initial load will be a bit slow, because it needs to scale up if it hasn't had traffic recently.
The accompanying B/E project for this is here.
- Docker
- Node JS (I used v18)
- Port 3000 & 3001 free on your machine
git clone https://github.com/chrisjpalmer/korean-restaurants
cd korean-restaurants
npm install
npm run dev
git clone https://github.com/chrisjpalmer/korean-restaurants-be
cd korean-restaurants-be
If you are a Makefile person:
make database
make build-docker
make serve-docker
If you are not a Makefile person:
./scripts/make-database.sh
./scripts/build-docker.sh
./scripts/serve-docker.sh
Open http://localhost:3000 to see the app.
- A list of korean restaurants in geojson format is statically served to the F/E. These are displayed on the map when the app loads.
- To find the nearest korean restaurant to the marker point, the B/E service queries the postgres database which contains the same list of restaurants.
I read this article by Michael Asher and wanted to see how quickly I could pick up a new software stack. I have never used postgis, mapbox, ogr2ogr OR geojson before. I'm also not a F/E developer by trade.
I came up with a simple concept, to build an app that could showcase my favourite korean restaurants and tell me where the closest one was - this is rather helpful as I live in Korea (at least for the next 12 months).
I spent in total 18 hours comprised of:
- 4 hours of initial research
- 4 hours on the B/E
- 8 hours on the F/E
- 2 hours of bug fixing/polishing/testing
To build this, the steps I took were.
- Plotted my favourite korean restaurants on google earth
- Converted the KML file to GeoJSON using ogr2ogr
- Loaded the GeoJSON into a Postgis enabled database using ogr2ogr.
- Tested out some queries to familiarize myself with Postgis
- Built a simple B/E to query the database.
- Built a basic F/E app using react + mapbox.
- Wired up my B/E and F/E
Update: CI/CD with Control Plane
All commits after June 15 were to set up my hosting on Control Plane. The commit history is a bit of a mess because I was just having some fun at this point.
- Postgis
- Mapbox
- Ogr2Ogr
- GeoJSON
- Bit more react
- I am a fast learner - learnt postgis, mapbox, ogr2ogr in a few hours
- I am versatile with technical detail
- I like to GSD (get stuff done) - if you dont ship it, you don't make money.
- I am organized - comments, code organization, documentation, diagrams are part of my trade.
I believe DecSecOps is an important part of software development. In this project I implemented a few good practices:
- Sensitive data stored in github secrets.
- Trivy image scanning before artifacts are published.
- Dependabot enabled so if a CVE is detected in a dependency being used, GitHub generates a PR with the dependency update.
- Automated CI/CD process to eliminate human error during deployment.
Ultimately to do DevSecOps properly, security needs to be in the mindset of the organization and be part of every process in the Software Development Life Cycle (SDLC). Here are some examples of things you could do in different stages of the SDLC to implement DevSecOps:
Requirements / Planning
- Are access controls implemented at the application level to keep users safe?
- Are there any escalation of privilege scenarios in the application level?
- Avoid misleading users into unsafe usage patterns that an attacker could take advantage of + remind them what the correct usage patterns are ("SafeBank will never ask for your password over the phone").
- Encourage MFA
Architectural Design
- Consider potential DoS attacks on architectural change.
- Consider potential escalation of privilege attacks on architectural change.
- Mitigate "unhappy paths" that lead to an inconsistent state across services.
- If SaaS platform, enforce Tenancy at the database level in every service.
- Is principle of least privilege implemented? - check every commponent, ask what privileges it has and why?
- Multiple protections for the same thing (E.g. dont expose insecure APIs in routing rules AND only whitelist secure APIs on security policies)
- Use of temporary credentials with credential manager such as Vault.
- Istio: enforce MTLs and default deny all service-to-service communication
unless explicitly whitelisted via
AuthorizationPolicy
.
Development
- Consider impacts of code to be written - could it be exploited?
- Write unit tests designed to break modules / exploit common attack vectors
- Prevent commiting secrets using git commit hooks.
- Static analysis tools
- Codebase scanning
- Build Best Practice Docker Images
- Docker Image scanning
Testing
- Write integration tests designed to break services / exploit common attack vectors.
- Write integration tests to validate security boundaries are implemented.
- Establish a culture of never exposing insecure APIs for testing even in the development environment. Solve using in-cluster integration testing (better still trust your Unit tests and dont expose at all).
Deployment
- In-cluster artifact scanning
- Chaos testing
- Run integration tests regularly
This application was deployed with Control Plane. Control Plane allows you to deploy containerized workloads to multiple cloud providers without having to manage the underlying infrastructure. Under the hood Control Plane uses kubernetes and istio. This allows an operator to define a simple definition of their workload, and have it deployed across cloud providers. This application is deployed across AWS and GCP clusters.
The B/E service for this application depends on a postgres database to operate. An RDS instance was deployed to AWS, and then linked to the Control Plane account using an Agent. Agents allows workloads deployed to Control Plane to consume services in another VPC or private network.