Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PTA RiskWatch - Compliance & Risk Monitoring Tool

A Flask-based web application for regulatory compliance and risk monitoring in the telecommunications sector. The tool implements a Key Risk Indicator (KRI) scoring model derived from Pakistan's telecom cybersecurity framework, supporting multi-tenant organisation isolation, historical trend analysis, side-by-side comparison, report export (CSV/PDF), and full audit logging.


Table of Contents


Requirements

  • Python 3.8 or higher
  • MySQL or MariaDB server
  • pip3 package manager
  • A Unix-like environment

Installation

  1. Clone or extract the project archive to a working directory.

  2. Create and activate a virtual environment:

python3 -m venv venv
source venv/bin/activate
  1. Install dependencies:
pip install -r requirements.txt

Configuration

  1. Copy the example environment file:
cp .env.example .env
  1. Edit .env with your database credentials. Use the dedicated application user created in the next section (not root):
MYSQL_HOST=localhost
MYSQL_USER=pta_app
MYSQL_PASSWORD=your_app_user_password
MYSQL_DB=PTA_RiskWatch_DB
SECRET_KEY=your_secure_secret_key

Security note: Never commit .env to version control. It is listed in .gitignore by default.


Database Setup

The application uses MySQL or MariaDB. On Kali Linux, MariaDB is the default provider.

1. Start the database server

sudo systemctl enable --now mysql
sudo systemctl start mysql

2. Authenticate as root (first-time setup only)

MariaDB on Kali uses Unix socket authentication for root by default. Open a root session:

sudo mysql

If you have previously set a root password, use:

mysql -u root -p

3. Create the database and a dedicated application user

Rather than running the application as root, create a least-privilege user that has access only to the application database:

CREATE DATABASE IF NOT EXISTS PTA_RiskWatch_DB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'pta_app'@'localhost' IDENTIFIED BY 'leopard324';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON PTA_RiskWatch_DB.* TO 'pta_app'@'localhost';
FLUSH PRIVILEGES;
EXIT;

CREATE, DROP, INDEX, and ALTER are needed on first run so Flask-SQLAlchemy can create the schema. Once the tables exist you can tighten permissions further by revoking those four grants and keeping only SELECT, INSERT, UPDATE, DELETE.

4. Verify the connection

mysql -u pta_app -p PTA_RiskWatch_DB

A successful login confirms the user and database are ready.


Running the Application

Ensure the virtual environment is activated and the database server is running, then:

python3 app.py

On first execution the application will automatically:

  • Create all database tables via SQLAlchemy.
  • Seed initial data: three telecom organisations (Telenor Pakistan, Jazz 5G Pakistan, Zong 5G), four user accounts (one admin + one per organisation), 14 KRI definitions with regulatory references, weights, and scoring thresholds, and sample KRI scores for the years 2015 through 2025.

The development server starts at http://127.0.0.1:5000.

To skip seeding (e.g. after the first run), the seed_data() function exits early if any organisation already exists in the database.


Default Credentials

Username Role Password Organisation
admin admin admin123 None (global access)
telenor org_user telenor123 Telenor Pakistan
jazz org_user jazz123 Jazz 5G Pakistan
zong org_user zong123 Zong 5G (CMPak)

All default passwords must be changed before any production or shared deployment.
Passwords can be updated from the My Profile page after logging in.


Features

Authentication & Access Control

  • Session-based login/logout using Flask-Login.
  • Two roles: admin (global access to all organisations) and org_user (restricted to their own organisation).
  • Public company self-registration creates a new organisation and an org_user account in one step.
  • Users can update their username and password from their profile page.

Dashboard

  • Displays the overall weighted risk score (0–100) and risk level (Low / Medium / High / Critical) for a selected organisation and year.
  • KRI summary cards show the count of indicators at each risk level.
  • Full KRI table with raw value, numerical score, weight, and contribution - colour-coded by risk level.
  • Year selector and (for admins) organisation selector for quick navigation.
  • Direct links to edit scores or add data for a new year.
  • One-click CSV and PDF report download.

KRI Score Management

  • Admin and org_user roles can enter or update raw KRI values (0–100%) for any organisation and year.
  • Numerical scores and weighted contributions are computed automatically on save using the configured threshold bands.
  • Existing values are pre-filled to allow partial updates.

Trend Analysis

  • Line chart (Chart.js) showing overall risk score over all available years for a selected organisation.
  • Tabular history with progress bars and risk-level badges per year.
  • Admin users can switch between organisations via a dropdown.

Comparison Engine

  • Company comparison (admin only): select 2–3 organisations and a year to produce a bar chart and a KRI-level breakdown table side-by-side.
  • Year comparison (all users): select 2–3 years for your own organisation to visualise how scores have shifted over time.

Report Export

  • CSV: KRI name, raw value, numerical score, weight, and contribution - plus an overall score row at the end.
  • PDF: formatted report via ReportLab with automatic page breaks for long KRI lists.
  • Access is restricted so org_users can only export their own organisation's data.

Audit Logging

  • Every login, logout, score update, report download, comparison, and registration event is recorded with a timestamp, the acting user, action type, and descriptive detail.
  • Audit log viewer (admin only) shows the 200 most recent entries.

Risk Scoring Model

The overall risk score is a weighted sum across 14 KRIs:

Overall Score = Σ (numerical_score_i × weight_i / 100)

Each KRI maps a raw percentage value to a numerical score via threshold bands:

Band Numerical Score Overall Contribution
Low 10 Low
Medium 40 Moderate
High 70 High
Critical 100 Maximum

The final score maps to a risk level as follows:

Score Range Risk Level
0 – 25 Low
26 – 50 Medium
51 – 75 High
76 – 100 Critical

KRI weights, threshold boundaries, regulatory references, and measurement methods are stored as data (not code) in the kri_definitions table, making reconfiguration possible without application changes.

The 14 KRIs cover obligations drawn from: PECA 2016, NCSP 2021, CTDISR-2025, PISF 2025, and CERT Rules 2023.


Project Structure

CSG-Project/
├── app.py               # Application factory and entry point
├── extensions.py        # Shared SQLAlchemy and LoginManager instances
├── models.py            # ORM models: Organisation, User, KRIDefinition, KRIScore, AuditLog
├── routes.py            # All Flask routes and business logic (Blueprint)
├── seed.py              # Database seeder: organisations, users, KRI definitions, sample scores
├── requirements.txt     # Python dependencies
├── .env                 # Runtime environment variables (not committed)
├── .env.example         # Environment variable template
├── .gitignore
├── README.md
└── templates/
    ├── base.html         # Shared layout: navbar, footer, Bootstrap 5, Chart.js
    ├── login.html        # Standalone login page
    ├── register.html     # Public company registration page
    ├── dashboard.html    # Main KRI dashboard
    ├── add_scores.html   # KRI score entry/edit form
    ├── trends.html       # Historical trend chart and table
    ├── compare.html      # Company and year comparison engine
    ├── profile.html      # User profile and password change
    └── audit.html        # Audit log viewer (admin only)

Troubleshooting

Connection refused

The database server is not running. Start it with:

sudo systemctl start mysql

Access denied for user 'pta_app'@'localhost'

The application user may not have been created, or the password in .env does not match. Re-run the CREATE USER and GRANT statements from the Database Setup section, then verify with:

mysql -u pta_app -p PTA_RiskWatch_DB

Unknown database 'PTA_RiskWatch_DB'

The database was not created. Run:

CREATE DATABASE IF NOT EXISTS PTA_RiskWatch_DB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Module not found errors

The virtual environment is not active, or dependencies were not installed:

source venv/bin/activate
pip install -r requirements.txt

Tables already exist but data is missing

The seeder exits early if any organisation row is present. To reseed from scratch, drop and recreate the database, then restart the application:

DROP DATABASE PTA_RiskWatch_DB;
CREATE DATABASE PTA_RiskWatch_DB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON PTA_RiskWatch_DB.* TO 'pta_app'@'localhost';

Can't connect to local server through socket '/run/mysqld/mysqld.sock'

To fix this issue, please run the following commands in the order.

sudo mkdir -p /run/mysqld
sudo chown mysql:mysql /run/mysqld
sudo chmod 755 /run/mysqld
sudo service mysql restart


Development Notes

  • All database queries go through SQLAlchemy's ORM - no raw string interpolation, preventing SQL injection.
  • Passwords are hashed with Werkzeug's generate_password_hash (PBKDF2-HMAC-SHA256 by default).
  • KRI thresholds are stored as JSON in the kri_definitions table; adjusting compliance thresholds requires only a data change, not a code deployment.
  • The UniqueConstraint on (organization_id, year, kri_id) in KRIScore prevents duplicate entries and makes upserts safe.
  • Chart data for the trends page is served via a lightweight /api/trends_data JSON endpoint, keeping the Jinja template free of large inline data blobs.
  • Bootstrap 5 and Chart.js are loaded from CDN - no local static assets are required.

Academic Context

This tool was developed as the semester project for Cyber Security Governance (CY-303) at the National Cyber Security Academy (NCSA), Air University, Islamabad. The KRI framework is based on Pakistan's published telecom cybersecurity regulations: PECA 2016, NCSP 2021, CTDISR-2025, PISF 2025, and CERT Rules 2023.


Contributers


About

A Flask-based web application for regulatory compliance and risk monitoring in the telecommunications sector.

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages