Michael McKibbin
← Back to projects

Project Outline

SecFlo: A Secure and Scalable Workflow Management System

Final Year Honours Project – First Class Honours BSc in Contemporary Software Development

The Design, Implementation, and Cloud Deployment of a Containerised Secure Workflow Application with Role-Based Access Control.

.NET 10 • Blazor Web App (Server) • ASP.NET Core Identity • Entity Framework Core • PostgreSQL • Docker • Traefik • GitHub Actions • GHCR • xUnit • bUnit • CI/CD

Role

Designer / Developer

Period

2026

Status

Completed

Results

Achieved First Class Honours with a grade of 86%

01

Project Overview

SecFlo – Secure Workflow Management System

SecFlo is a cloud-hosted workflow and case management application developed as my final year BSc (Hons) project. The aim of the project was to demonstrate how modern software engineering principles can be combined with secure application design and DevOps automation to create a lightweight, enterprise-style workflow platform. Rather than simply building another CRUD application, the project focuses on secure workflow management, controlled state transitions, role-based permissions, automated deployment, and maintainable cloud infrastructure.

The application was built using ASP.NET Core Blazor Server (.NET 10) with Entity Framework Core and PostgreSQL. User authentication is handled through ASP.NET Core Identity, implementing Role-Based Access Control (RBAC) with User, Staff, and Administrator roles. Users can create workflow cases, staff members can assign and manage work, administrators manage users and permissions, and every workflow transition is recorded to provide a complete audit trail. The application follows a structured workflow lifecycle consisting of New → Assigned → In Progress → Resolved → Closed, demonstrating secure business process management.

A major objective of the project was to gain practical experience with modern deployment practices. The application and database were containerised using Docker, deployed to an Ubuntu VPS, secured with Traefik and Let's Encrypt HTTPS, and delivered through a fully automated GitHub Actions CI/CD pipeline publishing immutable container images to the GitHub Container Registry (GHCR). During development I resolved several real-world deployment challenges involving authentication persistence, container image versioning, and cloud configuration, providing valuable hands-on experience beyond traditional software development.

The project was tested using multiple approaches including unit testing with xUnit, Blazor component testing with bUnit, integration testing, workflow validation, security testing, deployment verification, and negative testing. These tests confirmed the correct implementation of authentication, authorisation, workflow management, cloud deployment, and automated CI/CD processes, demonstrating a complete software engineering lifecycle from design through deployment.

Although originally developed as an academic project, SecFlo was intentionally designed using technologies and practices commonly found in production environments. It demonstrates experience with secure web application development, cloud-native deployment, containerisation, CI/CD automation, infrastructure management, and secure software engineering—skills directly applicable to modern Software Engineering, DevOps, Platform Engineering, and Cybersecurity roles.

02

Goals & Requirements

Primary Goals

  • Design and develop a secure workflow management application.
  • Implement authentication and Role-Based Access Control (RBAC).
  • Provide a structured and traceable case workflow lifecycle.
  • Apply modern full-stack software engineering and testing practices.
  • Containerise the application and supporting services using Docker.
  • Implement an automated CI/CD pipeline for reliable deployment.
  • Deploy and operate the system securely in a cloud-hosted Linux environment.

Key Requirements

  • Support User, Staff and Admin roles with appropriate permissions.
  • Allow users to create, view and track workflow cases.
  • Enable authorised staff to assign cases, add notes and update status.
  • Enforce valid workflow progression through New, Assigned, In Progress, Resolved and Closed states.
  • Maintain status history and traceability for workflow changes.
  • Store application and identity data persistently in PostgreSQL.
  • Enforce secure authentication, authorisation and HTTPS.
  • Support automated testing, containerised deployment and CI/CD.

03

Database Design

Database Schema

SecFlo uses a relational database structure centred on the Case entity, which represents an individual item progressing through the workflow. Each case stores its title, description, current workflow status, priority, creation and update timestamps, together with references to the user who created it and the user to whom it is currently assigned. This provides the core data required to manage ownership, assignment and progression throughout the lifecycle of a case.

User and security information is represented through ApplicationUser, Role, and UserRole entities. ApplicationUser extends the application's identity model with information such as the user's full name and creation date, while the Role and UserRole entities support the Role-Based Access Control (RBAC) system. This allows permissions to be associated with roles rather than individual users and supports the application's User, Staff and Administrator access levels.

Two additional entities provide traceability and supporting information for each case. CaseNote stores notes written against a case, linking each note to both its case and its author. CaseStatusHistory records changes to the workflow state, including the previous and new status, the user responsible for the change, the time it occurred and an optional comment. Maintaining status history separately from the current status allows the application to retain a chronological record of a case's progression rather than simply overwriting its previous state.

Relationships between these entities are managed through Entity Framework Core, with PostgreSQL providing persistent storage. The resulting schema separates workflow, identity, notes and historical data while maintaining explicit relationships between them. This supports data integrity and efficient querying while also providing the traceability required by a secure workflow application.

04

Technology Stack

The project was built using a modern technology stack, combining the power of .NET 10 with Blazor Server for the frontend, PostgreSQL for data persistence, and Docker for containerisation. The application leverages ASP.NET Core Identity for secure authentication and role-based access control, while Entity Framework Core provides an efficient ORM layer for database interactions. The deployment process is automated through GitHub Actions, with container images published to the GitHub Container Registry (GHCR) and deployed to an Ubuntu Linux server using Traefik as a reverse proxy.

Technologies Employed

  • ASP.NET Core (.NET 10)
  • Blazor Server
  • C#
  • PostgreSQL
  • Entity Framework Core
  • ASP.NET Core Identity
  • Docker & Docker Compose
  • Traefik Reverse Proxy
  • GitHub Actions
  • GitHub Container Registry (GHCR)
  • Ubuntu Linux
  • xUnit
  • bUnit
  • Git

05

Deployed Architecture

SecFlo is deployed using a containerised architecture on an Ubuntu VPS.

End users access the application through a standard web browser, with all external communication secured using HTTPS on port 443. Incoming requests are handled by a Traefik reverse proxy, which provides the public entry point to the deployment, manages TLS certificates, and routes requests to the appropriate application service without directly exposing the application container to the internet.

Within the Docker network, the Blazor Server application provides the user interface, application logic, authentication, and Role-Based Access Control (RBAC). Persistent application and identity data is stored in PostgreSQL, with database access managed through Entity Framework Core and Npgsql.

Separating the application, database, and reverse-proxy responsibilities into containerised services provides a portable and reproducible deployment while keeping internal services isolated from direct public access.

06

Key Features

  • Secure authentication and authorisation
  • Role-Based Access Control (RBAC)
  • Workflow case management
  • Workflow state machine
  • Case assignment
  • Status history and audit trail
  • PostgreSQL persistence
  • Containerised deployment
  • Automated CI/CD pipeline
  • HTTPS with Let's Encrypt
  • Automated Docker image publishing
  • Cloud-hosted deployment

SecFlo combines secure application development with practical workflow management and modern DevOps practices.

The system provides controlled case progression, role-based permissions and traceable status history, backed by persistent PostgreSQL storage.

Its containerised architecture and automated CI/CD pipeline extend the project beyond application development to demonstrate secure, repeatable deployment to a live cloud environment.

07

Technical Highlights

Architecture

SecFlo was developed as a Blazor Server application using ASP.NET Core and .NET 10, with application logic, authentication and workflow management integrated within a strongly typed C# environment. Entity Framework Core provides the data-access layer, with PostgreSQL used for persistent storage of identity information, workflow cases, notes and status history.

The production environment uses a containerised, multi-service architecture hosted on an Ubuntu VPS. Docker Compose manages the application and PostgreSQL services, while Traefik acts as the external reverse proxy, routing HTTPS traffic to the application across an internal Docker network. Configuration is supplied through environment variables, allowing development and production settings to remain separate from the application source code.

Quality

SecFlo uses a layered testing strategy covering application logic, UI components, database integration, workflow behaviour, security controls and the deployed environment. xUnit provides automated unit testing, while bUnit tests Blazor components using mocked services and authentication states. Integration testing uses real containerised PostgreSQL instances to verify database persistence and Entity Framework behaviour.

Testing is also incorporated into the GitHub Actions CI/CD pipeline, allowing changes to be built and validated as part of the delivery process. Deployment testing verifies container startup, database connectivity, HTTPS availability, health endpoint responses and the exact container image deployed to production. Using immutable Docker image digests provides additional traceability between the tested build artefact and the version running on the VPS

Security

Security is built into both the application and deployment architecture. ASP.NET Core Identity provides authentication, secure password handling and session management, while Role-Based Access Control (RBAC) separates permissions between User, Staff and Administrator roles. Authorisation is enforced server-side as well as in the user interface, and database queries restrict users to data they are permitted to access rather than relying solely on hidden UI controls.

The deployed system is protected using HTTPS/TLS, with Traefik providing reverse-proxy routing and automatic certificate management through Let's Encrypt. Sensitive configuration such as database credentials and deployment SSH keys is kept outside the source code using environment variables and GitHub Secrets. ASP.NET Core Data Protection keys are stored in persistent Docker storage so authentication and antiforgery protection remain valid when application containers are replaced during deployment.

09

Project Demonstration

A brief demonstration video showing the project in use.

10

Challenges

Deployment Pipeline and Container Versioning

One of the most significant technical challenges occurred while developing the automated deployment pipeline. GitHub Actions successfully built and published a new Docker image, and the deployment workflow itself reported success, but the VPS continued running an older version of the application. This made the problem particularly interesting because each individual stage appeared to be working correctly, while the final deployed system did not match the source code that had triggered the pipeline.

I investigated the problem across the complete deployment chain rather than assuming that a successful CI/CD job meant the correct application had been deployed. This involved checking the image produced by GitHub Actions, inspecting the images stored in GitHub Container Registry (GHCR), examining the environment variables generated during deployment, reviewing the resolved Docker Compose configuration, and finally comparing these with the container actually running on the VPS. The investigation identified an incorrect environment-variable reference in the deployment process, which caused Docker Compose to continue using a previously cached image instead of the newly built version.

The immediate problem could have been solved by correcting the image-tag substitution, but the issue exposed a broader weakness in relying on mutable Docker tags such as latest. I therefore improved the deployment process to use immutable container image digests. Each digest uniquely identifies the exact image produced by the pipeline, allowing the deployed container to be verified against the CI/CD artefact and making previous versions easier to identify for rollback. Additional deployment logging was also introduced so that the resolved configuration and deployed image could be inspected when diagnosing future problems.

There was a trade-off in making the deployment process more explicit. Using a simple latest tag would have produced a shorter and easier-to-understand configuration, whereas digest-based deployment required additional pipeline logic and environment management. The additional complexity was justified by the improvement in repeatability, traceability and deployment confidence: the pipeline could now demonstrate not merely that an application container was running, but that the specific image built and tested by the pipeline was the image running in production.

Runtime architecture diagram

12

Lessons Learned

SecFlo reinforced the importance of treating deployment, security and testing as part of application development rather than as tasks performed after the application is complete. Containerising the system early and maintaining similar local and production environments proved particularly valuable, as did automating build, test and deployment processes through GitHub Actions. I would use this approach again on future projects, together with the layered testing strategy used to validate application logic, UI components, database integration and the deployed environment.

The project also demonstrated how production deployment can expose problems that are difficult to reproduce during local development. Issues involving container image versioning, environment configuration and ASP.NET Core Data Protection key persistence required investigation across several layers of the system. Resolving these problems developed my practical understanding of Docker, Linux hosting, CI/CD pipelines, application configuration, reverse proxies, HTTPS and troubleshooting distributed application environments. In particular, moving to immutable container image digests demonstrated the value of making deployments reproducible and verifiable rather than simply relying on a successful pipeline result.

If starting the project again, I would introduce some of the production-oriented infrastructure earlier in development and place greater emphasis on observability and automated integration testing from the beginning. Centralised structured logging and monitoring would make diagnosing problems across containers easier, while earlier end-to-end testing against an environment closely matching production could identify configuration and deployment issues sooner. I would also consider defining workflow states and transition rules more formally from the outset, making the workflow engine easier to extend as the application grows.

Further development could extend SecFlo with external identity providers and MFA, enhanced audit logging, notifications, reporting dashboards and configurable workflow templates. On the infrastructure side, Infrastructure as Code, automated security scanning, centralised logging and monitoring, and eventually orchestration using Kubernetes would provide natural opportunities to evolve the project towards a more production-oriented platform. A longer-term extension could develop the system into a multi-tenant SaaS application, allowing multiple organisations to operate independent workflow environments on the same platform.

12

Project Report

The full report for the SecFlo project is available in PDF format. It provides a detailed overview of the project objectives, design decisions, implementation details, testing strategies, deployment architecture, and lessons learned. The report serves as a comprehensive reference for understanding the development process and technical considerations involved in creating the SecFlo application.

You can view the report directly in your browser using the embedded PDF viewer below, or open it in a new tab for a full-screen experience.