This project is a technical proof-of-concept demonstrating the architectural shift from Legacy Perimeter Security (Firewalls) to Secure Access Service Edge (SASE).
In a modern decentralized environment, the traditional "Castle-and-Moat" firewall is no longer sufficient. This lab implements a Software-Defined Perimeter using Zero Trust Network Access (ZTNA) principles, where identity, not the IP address, is the new security boundary.
Traditional network security relied on a "safe" perimeter (VPNs or Physical Offices). SASE (Secure Access Service Edge) flips this model by moving the security stack to the cloud.
- Identity-as-a-Perimeter: Access is granted based on who you are, regardless of where you connect from.
- Cloud-Native Convergence: Security functions (FWaaS, ZTNA) are moved to a distributed Point of Presence (PoP).
- Continuous Adaptive Risk Assessment: Every request is inspected, authenticated via JWT (JSON Web Token), and decrypted via AES, ensuring no "implicit trust" exists within the network.
The communication follows a strict Zero Trust Network Access (ZTNA) protocol:
- Client-Side preparation: The client generates a stateless Identity Token (JWT) and wraps the data in an AES-256 (Fernet) encrypted envelope.
- Edge processing (PoP):
- Identity Challenge: The Gateway validates the JWT signature using a shared secret.
- Privacy Enforcement: The Gateway decrypts the payload only if the identity is verified.
- Contextual Access: Access is granted only if both cryptographic checks pass, simulating a "Service-to-Service" secure tunnel.
The problem: Traditional session-based authentication requires a centralized database, creating a bottleneck and a single point of failure.
The solution: We implemented JSON Web Tokens (JWT).
Why?: JWTs are stateless and self-contained. The SASE Gateway can verify the user's identity and roles without querying a central database, allowing the infrastructure to scale horizontally across multiple Docker nodes or global regions.
The Problem: Standard TLS (HTTPS) protects the connection but terminates at the first proxy or load balancer, leaving data exposed within the service provider's internal network.
The Solution: Application-Layer Encryption using AES-256.
The Benefit: By encrypting the payload before transmission, we ensure End-to-Middle Privacy. Even if the TLS tunnel is intercepted or terminated at a cloud broker, the raw data remains opaque to the infrastructure, fulfilling the "Zero Trust" requirement of protecting data-in-transit.
The Problem: Cryptographic operations, like AES decryption, are CPU-intensive and can be used as a vector for Denial of Service (DoS) attacks.
The Solution: A tiered validation pipeline.
-
Low-Cost Check: Verification of the x-identity-token header presence.
-
Medium-Cost Check: JWT signature verification (Fast).
-
High-Cost Check: AES decryption, which is performed only for authenticated users.
- The Result: This design ensures the Gateway rejects malicious or anonymous traffic at the earliest possible stage, preserving computational resources for legitimate users.
graph LR
A[Remote User] -- 1. Signed JWT --> B((SASE PoP Gateway))
A -- 2. AES Encrypted Data --> B
B -- 3. Logic Validation --> C{Decision}
C -- Valid --> D[Internal Resource]
C -- Invalid --> E[Access Denied]
- Language: Python 3.10
- Web Framework: FastAPI (Uvicorn)
- Security: PyJWT (Identity), Cryptography/Fernet (AES-256)
- DevOps: Docker & Docker Compose
To run this lab, you need Docker and Docker Compose installed on your system (Linux or WSL2).
sudo apt update
sudo apt install docker.io docker-compose-v2
sudo usermod -aG docker $USER
# Note: restart your terminal after thisClone the repository and set up the environment:
git clone https://github.com/frable1/SASE-ZeroTrust-Lab.git
cd SASE-ZeroTrust-Lab
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt- Generate Keys: create your unique encryption keys (stored in .env):
python3 setup_keys.py- Start the PoP: launch the containerized Gateway:
docker compose up --build- Run Client: in a new terminal, simulate an authorized access:
python3 -m client.clientTo verify the lab is running correctly, you should see logs similar to these:
- Key Generation (setup_keys.py)
[SUCCESS] .env file created successfully.
Remember: This file should NOT be uploaded to GitHub!
- SASE Gateway Startup (docker compose) The PoP Gateway will start listening for identity-based requests:
sase-gateway-1 | INFO: Application startup complete.
sase-gateway-1 | INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
- Authorized Access (client.client) When the client successfully authenticates and sends data:
[Client] Generated JWT token: eyJhbGciOiJIUzI1NiIs...
[Client] Cipher: gAAAAABqBifvidx8cTiV...
[Success] Response from Gateway:
{
'status': 'ACCESS GRANTED',
'identity': {'sub': 'sase_identity_01', 'role': 'developer', ...},
'message': 'Request access to the internal GitLab server.'
}
To verify the security enforcement of the SASE Gateway, you can use the built-in simulation tools.
Run the interactive attacker simulation to see how the Gateway handles different threat scenarios in real-time:
python3 -m attacker.attacker| Scenario | Tool | Expected Result |
|---|---|---|
| No identity | attacker.attacker | 401 - Unauthorized |
| Fake identity | attacker.attacker | 403 - Forbidden |
| Data tampering | attacker.attacker | 400 - Decryption Failed |
| Authorized user | client.client | 200 OK - Access Granted |
The integrity of the Zero Trust pipeline is verified through automated unit tests. These tests ensure that the Gateway correctly handles identity validation, cryptographic checks, and data integrity.
To execute the test suite, ensure the SASE Gateway - Docker - is running, then use:
# Install testing dependencies
pip install pytest
# Run the validation suite
python3 -m pytest- Identity Enforcement: Verifies that anonymous requests are blocked (401 Unauthorized).
- Cryptographic Signature: Ensures counterfeit or tampered JWTs are rejected (403 Forbidden).
- Payload Integrity: Confirms that malformed or cleartext data triggers a decryption failure (400 Bad Request).
- Zero Trust Success: Validates the end-to-end flow for authorized users (200 OK).
If you see permission denied while trying to connect to the Docker daemon socket:
Fix: Run sudo usermod -aG docker $USER and then restart your WSL/terminal session. Alternatively, use newgrp docker to apply changes immediately.
If Docker or Uvicorn fails to start because the port is taken:
Fix: Check for running processes with lsof -i :8000 and kill them, or ensure you stopped any previous uvicorn instances before running docker compose.
If you try to run the client/attacker scripts and Python can't find the core module:
Fix: Always run the scripts from the root directory using the -m flag:
python3 -m client.client instead of python3 client/client.py.
If the client fails even with the correct setup:
Fix: You might have regenerated the keys in .env without restarting the Gateway. Run docker compose up --build to ensure the Gateway is using the latest cryptographic keys.
Author: Francesco Ble, Date: May 14-15, 2026, Academic Context: Network Security & Zero Trust Evolution Study.