Learn to build production-ready AI agents for Palo Alto Networks Strata Cloud Manager using LangGraph, LangChain, and Claude
- Overview
- GitHub Codespaces Setup
- Who This Is For
- Learning Path
- Project Structure
- Installation
- Quick Start
- Notebooks
- Workshop Phases
- Key Patterns
- Contributing
- Resources
- License
- Acknowledgements
This comprehensive workshop teaches network security engineers how to build AI-powered automation agents using LangGraph and Claude AI. Through 7 workshop notebooks (101-106, 108, 110) delivered in 3-4 hours, you'll master everything from type annotations to advanced ReAct agents, with 4 additional notebooks available for self-study.
Express Workshop Format (3-4 Hours):
- Survey/Exposure Approach: Core concepts covered in workshop, mastery through self-study
- Demo-Focused: 70/30 instructor demonstrations with student follow-along
- Production Patterns: Real-world SCM automation examples
- Cost-Aware: Foundations (101-106) use mock data - no API costs
- Flexible Learning: All 11 notebooks available for comprehensive self-paced learning
What Makes This Workshop Unique:
- Time-Efficient: Complete in 3-4 hours with optional deep-dive content
- Progressive Learning: Start with fundamentals, build to advanced AI agents
- Network-Focused: All examples use real network automation scenarios
- Dual-Path: Express workshop + extended self-study materials
11 comprehensive notebooks
- Progressive learning from TypedDict basics to Human-in-the-Loop patterns
- Each notebook builds on previous concepts with hands-on exercises
Real SCM integration
- Address objects, address groups, and tags
- Security rules and NAT policies
- Production-ready API patterns with pan-scm-sdk
Progressive complexity
- Start with single-node graphs
- Build to multi-tool AI agents
- Master conditional routing and loops
Cost-aware design
- Phase 1 notebooks (101-107) use mock data - no API costs
- Phase 2 notebooks (108-111) optional LLM integration
- Learn fundamentals before spending on AI
Production patterns
- Error handling and validation
- State management best practices
- Retry logic and pagination
Complete documentation
- Detailed notebook summaries
- Comprehensive setup guides
- Real-world SCM examples
Zero-install development environment in your browser
GitHub Codespaces provides a complete, pre-configured development environment without any local setup. This is the fastest way to get started with the workshop.
-
Fork this repository to your own GitHub account
- Click the "Fork" button at the top right of this page
- This creates your own copy of the workshop
-
Open in your Codespace
- From your forked repository, click the green "Code" button
- Select the "Codespaces" tab
- Click "Create codespace on main"
- Wait 2-3 minutes for the environment to build
-
Start learning
- Jupyter Lab automatically opens in your browser
- Navigate to
notebooks/and open101_type_annotations.ipynb - All dependencies are pre-installed and ready to use
β No local setup required - Everything runs in the cloud β Pre-configured environment - Python, Jupyter, and all dependencies ready β Works anywhere - Any device with a web browser β Free tier available - 60 hours/month free for personal accounts β Your own workspace - Make changes without affecting the original repo
For notebooks 108-111, you'll need to add your Anthropic API key:
# In the Codespace terminal
cp .env.template .env
# Edit .env and add your key
nano .envIf you prefer local development, see the Installation section below for complete setup instructions.
If you work with Palo Alto Networks firewalls and want to leverage AI for automation, this workshop is for you:
- Network administrators managing firewall configurations
- Security engineers building automation workflows
- DevOps/NetOps professionals implementing Infrastructure as Code
- Anyone interested in AI-powered network automation
Required Knowledge:
- Basic Python syntax (variables, functions, loops, dictionaries)
- Familiarity with Palo Alto Networks concepts (zones, policies, address objects)
- Understanding of network security fundamentals
Required for Advanced Notebooks (108-111):
- Anthropic API key (get one at console.anthropic.com)
- Budget awareness: ~$0.25 per 1M tokens for Claude Haiku
NOT Required:
- Prior LangGraph or LangChain experience
- Deep machine learning knowledge
- Advanced Python programming skills
The workshop follows a carefully designed progression:
Foundations (101-107) LLM Integration (108-111)
β β
Type Annotations β First LLM Integration
Core Concepts β Conversational Memory
Your First Graph β ReAct Agents with Tools
State Management β Human-in-the-Loop
Sequential Workflows
Conditional Routing
Looping Workflows
- Master LangGraph fundamentals with pure workflow mechanics
- Build confidence with real SCM automation patterns
- Learn state management, routing, and loops
- Integrate Claude AI into your workflows
- Build conversational agents with memory
- Create ReAct agents that use tools intelligently
- Implement human-in-the-loop collaboration patterns
naf-ai-agents-workshop/
βββ .devcontainer/ # GitHub Codespaces configuration
β βββ devcontainer.json
β βββ README.md
βββ .github/ # GitHub templates and workflows
β βββ ISSUE_TEMPLATE/
βββ docs/ # Workshop documentation
β βββ examples/ # SCM Python examples
β β βββ address_objects.py
β β βββ address_groups.py
β β βββ security_policy.py
β β βββ nat_policy.py
β β βββ services.py
β β βββ service_groups.py
β β βββ tags.py
β βββ NOTEBOOK_CREATION_GUIDE.md
β βββ STUDENT_SETUP_GUIDE.md
β βββ TROUBLESHOOTING.md
β βββ WORKSHOP_OUTLINE.md
β βββ llms.txt # LLM-friendly documentation
βββ notebooks/ # Express Workshop notebooks (streamlined)
β βββ 101_type_annotations.ipynb
β βββ 102_core_concepts.ipynb
β βββ 103_your_first_graph.ipynb
β βββ 104_state_management.ipynb
β βββ 105_sequential_workflows.ipynb
β βββ 106_conditional_routing.ipynb
β βββ 107_looping_workflows.ipynb
β βββ 108_first_llm_integration.ipynb
β βββ 109_conversational_memory.ipynb
β βββ 110_react_agents_with_tools.ipynb
β βββ 111_human_in_the_loop.ipynb
βββ notebooks-extended/ # Comprehensive versions for deep-dive learning
β βββ 101_type_annotations.ipynb
β βββ 102_core_concepts.ipynb
β βββ 103_your_first_graph.ipynb
β βββ 104_state_management.ipynb
β βββ 105_sequential_workflows.ipynb
β βββ 106_conditional_routing.ipynb
β βββ 107_looping_workflows.ipynb
β βββ 108_first_llm_integration.ipynb
β βββ 109_conversational_memory.ipynb
β βββ 110_react_agents_with_tools.ipynb
β βββ 111_human_in_the_loop.ipynb
βββ scripts/ # Utility scripts
β βββ clean_notebook.py
β βββ setup_git_filters.sh
βββ src/ # Source code modules
β βββ cli/ # CLI application
β β βββ app.py
β β βββ __main__.py
β β βββ commands/
β βββ core/ # Core functionality
β β βββ client.py
β β βββ config.py
β β βββ state.py
β βββ main.py # Monolithic workflow
β βββ README.md
βββ .env.template # Environment configuration template
βββ .gitignore # Git ignore rules
βββ .gitattributes # Git attributes for notebook filtering
βββ CLAUDE.md # Claude Code instructions
βββ CONTRIBUTING.md # Contribution guidelines
βββ Makefile # Workshop automation commands
βββ pyproject.toml # Python project configuration
βββ ruff.toml # Ruff linter configuration
βββ WORKSHOP_FAQ.md # Frequently asked questions
βββ WORKSHOP_PLAN.md # Workshop planning document
βββ README.md # This file
- Python 3.11+ (download)
- uv package manager (recommended) or pip
git clone https://github.com/cdot65/naf-ai-agents-workshop.git
cd naf-ai-agents-workshopUsing uv (recommended):
# Install uv if you don't have it
curl -LsSf https://astral.sh/uv/install.sh | sh
# Setup the workshop environment
make setupUsing pip:
# Create virtual environment
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install dependencies
pip install -e .# Copy the environment template
cp .env.template .env
# Edit .env and add your Anthropic API key
# (Only needed for notebooks 108-111)For notebooks 101-107: No API key required - you can start learning immediately!
For notebooks 108-111: Get your API key from Anthropic Console
# Start Jupyter Lab
make jupyter
# Jupyter will open automatically in your browser
# Navigate to notebooks/ and open 101_type_annotations.ipynb to begin!# One-command setup
make setup
# Edit .env with your API key (for notebooks 108-111 only)
nano .env
# Launch Jupyter Lab for interactive learning
make jupyter# Setup environment
make setup
# Launch Jupyter Lab
make jupyter
# In Jupyter, navigate to notebooks/ and start with:
# 101_type_annotations.ipynb# Test individual notebooks
make test-101 # Notebook 101: Type Annotations
make test-102 # Notebook 102: Core Concepts
make test-103 # Notebook 103: Your First Graph
make test-104 # Notebook 104: State Management
make test-105 # Notebook 105: Sequential Workflows
make test-106 # Notebook 106: Conditional Routing
make test-107 # Notebook 107: Looping Workflows
# Test all Phase 1 notebooks
make test-phase1
# Test Phase 2 notebooks (requires API key)
make test-108 # Notebook 108: First LLM Integration
make test-109 # Notebook 109: Conversational Memory
make test-110 # Notebook 110: ReAct Agents with Tools
make test-111 # Notebook 111: Human-in-the-Loop
# Test all Phase 2 notebooks
make test-phase2
# Test everything
make test-all
# Clean outputs
make clean
make clean-phase1 # Clean only Phase 1 outputs
make clean-phase2 # Clean only Phase 2 outputs# Setup and Environment
make setup # Install dependencies and configure environment
make dev # Install with dev dependencies
make jupyter # Launch Jupyter Lab
# Testing Notebooks
make test-101 through test-111 # Test individual notebooks
make test-phase1 # Test all Phase 1 notebooks (101-107)
make test-phase2 # Test all Phase 2 notebooks (108-111)
make test-all # Test all notebooks
# Utilities
make clean # Clear all notebook outputs
make clean-phase1 # Clear Phase 1 notebook outputs
make clean-phase2 # Clear Phase 2 notebook outputs
make format # Format code with black
make lint # Run flake8 linting
make help # Show all available commandsPhase 1 - Foundations (No API Key Required)
| # | Notebook | Duration | Format | Topics |
|---|---|---|---|---|
| 101 | Type Annotations | ~10-15 min | Demo | TypedDict essentials for LangGraph |
| 102 | Core Concepts | ~25 min | Hands-on | State, Nodes, Graphs, Edges (streamlined) |
| 103 | Your First Graph | ~15 min | Demo | Building single-node graphs |
| 104 | State Management | ~25 min | Hands-on | Complex multi-field states (streamlined) |
| 106 | Conditional Routing | ~30-35 min | Hands-on | Conditional routing patterns |
Phase 2 - LLM Integration (API Key Required)
| # | Notebook | Duration | Format | Topics |
|---|---|---|---|---|
| 108 | First LLM Integration | ~20-25 min | Demo | Claude integration, simple bots |
| 110 | ReAct Agents with Tools | ~30-35 min | Demo | Tools, reducers, ReAct pattern (capstone) |
Total Workshop Time: ~155-180 minutes + breaks = 3.1-3.5 hours
| # | Notebook | Duration | Level | Topics |
|---|---|---|---|---|
| 105 | Sequential Workflows | ~35 min | Extended | Multi-node pipelines (deep-dive) |
| 107 | Looping Workflows | ~25 min | Advanced | Retry logic, pagination |
| 109 | Conversational Memory | ~25 min | Extended | Message history (concepts in 110) |
| 111 | Human-in-the-Loop | ~20 min | Advanced | Interactive collaboration patterns |
Self-Study Path: Additional ~2-3 hours for comprehensive mastery
For students who want to explore concepts in greater depth, the notebooks-extended/ directory contains comprehensive versions of all workshop notebooks with:
- Additional examples and exercises - More hands-on practice with complex scenarios
- Extended explanations - Deeper coverage of advanced patterns and edge cases
- Production patterns - Additional real-world SCM automation examples
- Alternative approaches - Multiple ways to solve the same problems
- Troubleshooting guides - Common pitfalls and how to avoid them
During the Workshop:
- Stick to the
notebooks/directory for the Express workshop experience - Extended notebooks contain too much content for the 3-4 hour format
After the Workshop:
- Work through
notebooks-extended/at your own pace for mastery - Use them as reference material when building your own projects
- Ideal for self-paced learning or study groups
Recommended Approach:
- Complete Express workshop using
notebooks/(3-4 hours) - Build confidence with the core patterns
- Return to
notebooks-extended/for deeper understanding - Focus on notebooks relevant to your specific use cases
| Feature | notebooks/ (Express) |
notebooks-extended/ (Comprehensive) |
|---|---|---|
| Duration per notebook | 10-40 min | 30-60 min |
| Content focus | Core concepts, survey | Deep-dive, mastery |
| Examples | Essential patterns | Multiple approaches |
| Exercises | Guided practice | Challenge problems |
| Best for | Workshop delivery | Self-paced learning |
**101: Type Annotations** - Foundation for type-safe automation
Learning Objectives:
- Master TypedDict for structured dictionary schemas
- Use Union and Optional types effectively
- Apply Lambda functions for data transformation
- Build SCM address object and security rule structures
Key Takeaways:
- TypedDict is critical for LangGraph state definitions
- Type annotations prevent configuration errors before runtime
- Real SCM API structures match your TypedDict schemas exactly
Hands-On:
- Build address object TypedDict with 4 fields
- Create security policy state schema with validation
- Use lambda to filter rules by action, tags, zones
**102: Core Concepts** - Understanding LangGraph fundamentals
Learning Objectives:
- Define State schemas using TypedDict patterns
- Create Nodes that process and update state
- Build StateGraph structures connecting nodes
- Use Edges to define workflow execution order
Key Takeaways:
- State is shared data that flows through your graph
- Nodes are Python functions that update state
- Graphs compile into executable applications
Hands-On:
- Build 3-node address object pipeline (parse β validate β format)
- Design security policy state schema with 10+ fields
- Add error handling to workflows
**103: Your First Graph** - Building your first LangGraph application
Learning Objectives:
- Create simple single-node graphs
- Compile and invoke graphs with initial state
- Understand state flow through nodes
- Visualize graph structure with mermaid diagrams
Key Takeaways:
- START β node β END is the simplest pattern
- Nodes return partial state updates
- Graph.compile() creates executable applications
Hands-On:
- Build extended address validation workflow with 3 fields
- Add folder validation to workflow
- Create multi-field state with validation tracking
**104: State Management** - Working with complex data structures
Learning Objectives:
- Design multi-field state schemas with diverse data types
- Implement safe state access patterns
- Handle optional fields and defaults
- Build complex nested SCM structures
Key Takeaways:
- State can hold strings, lists, integers, booleans, dictionaries
- Only read fields that were provided or set by previous nodes
- Progressive complexity: start simple, scale up
Hands-On:
- Build address type validator supporting IP/FQDN/Range types
- Create advanced metrics calculator
- Design complete SCM workflow state with 10+ fields
**105: Sequential Workflows** - Multi-node automation pipelines
Learning Objectives:
- Chain nodes together using add_edge()
- Implement error handling across workflow steps
- Build complete SCM workflows (Tag β Address β Group)
- Manage dependencies between steps
Key Takeaways:
- Sequential execution via explicit edge connections
- State accumulates through pipeline
- Error propagation across nodes
Hands-On:
- Build 3-node SCM address object workflow
- Add comprehensive error handling
- Implement retry logic for failed API calls
**106: Conditional Routing** - Decision-making workflows
Learning Objectives:
- Use add_conditional_edges() for dynamic routing
- Create router functions with Literal return types
- Implement branching based on state conditions
- Apply network ACL analogy to routing logic
Key Takeaways:
- Router functions decide path without modifying state
- Lambda passthrough pattern for router nodes
- Path maps connect edge names to destination nodes
- Sequential patterns assumed from notebook 102
Hands-On:
- Build configuration change router (3-way routing)
- Implement environment-based routing (dev/stage/prod)
- Create address type validator with 3 validation paths
Note: This notebook focuses exclusively on conditional routing. Sequential workflow patterns are assumed knowledge from notebook 102.
**107: Looping Workflows** - Retry and iteration patterns
Learning Objectives:
- Create self-referencing edges for loops
- Implement retry logic with counter-based termination
- Build pagination patterns for API responses
- Design safe termination conditions
Key Takeaways:
- Loop pattern: initialize β process β check β [loop or exit]
- ALWAYS check max counter BEFORE success condition
- Four essential elements: counter, processor, router, conditional edge
Hands-On:
- Build SCM address list pagination workflow
- Implement retry logic with exponential backoff
- Create HA sync status polling workflow
**108: First LLM Integration** - Adding AI to your workflows
Learning Objectives:
- Integrate Claude AI into LangGraph workflows
- Define state structures for handling AI messages
- Initialize and invoke Anthropic models
- Understand limitations of stateless bots
Key Takeaways:
- LangChain and LangGraph work together seamlessly
- HumanMessage represents user input
- Simple bots don't remember conversation context
Hands-On:
- Build PAN-OS query bot for firewall questions
- Test bot with various configuration scenarios
- Demonstrate the memory problem with multi-turn conversations
**109: Conversational Memory** - Building stateful AI agents
Learning Objectives:
- Use HumanMessage and AIMessage for conversation tracking
- Implement manual conversation history management
- Understand token costs and conversation growth
- Apply trimming strategies to control costs
Key Takeaways:
- Union[HumanMessage, AIMessage] for mixed message lists
- Manual append of AI responses to state
- Token costs grow linearly with conversation length
- Trimming trade-offs: cost savings vs. context loss
Hands-On:
- Build multi-turn conversation with context retention
- Implement JSON persistence and loading
- Add window trimming with configurable size
- Calculate token costs for long conversations
**110: ReAct Agents with Tools** - Reasoning and Acting pattern
Learning Objectives:
- Master add_messages reducer for automatic state management
- Create custom tools with @tool decorator
- Build tool-calling agents with LLM decision-making
- Implement multi-tool workflows
Key Takeaways:
- Annotated[Sequence[BaseMessage], add_messages] eliminates manual state management
- Tool docstrings are critical for LLM tool selection
- ReAct pattern: Reasoning (LLM decides) + Acting (tools execute)
Hands-On:
- Create tools for PAN-OS version checking and upgrade planning
- Build agent that chains multiple tool calls intelligently
- Implement error handling in tools
- Add configuration validation tools
**111: Human-in-the-Loop** - Interactive AI collaboration
Learning Objectives:
- Implement human-in-the-loop patterns for AI collaboration
- Build interactive configuration drafting assistant
- Create approval workflows with explicit human control
- Route based on tool selection (update vs. save)
Key Takeaways:
- HITL vs ReAct: different routing for update/save tools
- Interactive input() within node functions
- Iterative refinement until human approves
- Global state management for learning purposes
Hands-On:
- Build NAT policy drafting workflow
- Implement configuration validation before save
- Create multi-step configuration wizard
- Add error detection and suggestions
Format: Instructor-led with 70/30 demo-focused delivery Target: Survey/exposure to core concepts with hands-on for critical patterns
Notebooks: 101-104 (No API Key Required)
- 101 (10-15 min): TypedDict essentials - Demo
- 102 (25 min): State, Nodes, Edges - Hands-on
- 103 (15 min): First graph - Demo
- 104 (25 min): Complex state - Hands-on
- Buffer: 10-15 min
What You'll Learn: Type-safe state management, building nodes and graphs
Notebooks: 106 (No API Key Required)
- 106 (30-35 min): Conditional routing - Hands-on
- Buffer: 15 min
What You'll Learn: Conditional routing patterns (sequential patterns assumed from 102)
Setup API keys for Phase 2
Notebooks: 108, 110 (API Key Required)
- 108 (20-25 min): LLM integration - Demo
- 110 (30-35 min): ReAct agents - Demo (capstone)
- Buffer/Q&A: 15-20 min
What You'll Learn: Claude AI integration, ReAct pattern with tools, reducers
Express Workshop Checklist:
- 101: TypedDict essentials
- 102: Core concepts (State, Nodes, Graphs, Edges) - streamlined
- 103: First single-node graph
- 104: Complex multi-field states - streamlined
- 106: Conditional routing patterns
- 108: First LLM integration
- 110: ReAct agents with tools
For comprehensive mastery, complete independently:
- 105 (35 min): Sequential workflows deep-dive
- 107 (25 min): Looping workflows (advanced)
- 109 (25 min): Conversational memory (extended)
- 111 (20 min): Human-in-the-loop (advanced)
π‘ Pro Tip: After completing the self-study notebooks, explore notebooks-extended/ for even deeper coverage with additional examples, exercises, and production patterns. See the Extended Notebooks section for details.
graph = StateGraph(State)
graph.add_node("process", process_function)
graph.set_entry_point("process")
graph.set_finish_point("process")
app = graph.compile()graph.add_edge(START, "validate")
graph.add_edge("validate", "create")
graph.add_edge("create", "verify")
graph.add_edge("verify", END)graph.add_node("router", lambda state: state)
graph.add_conditional_edges(
source="router",
path=router_function,
path_map={"path_a": "node_a", "path_b": "node_b"}
)def should_continue(state) -> Literal["loop", "exit"]:
if state["counter"] >= state["max"]:
return "exit" # Safety!
return "loop"
graph.add_conditional_edges("check", should_continue,
{"loop": "process", "exit": END})messages: Annotated[Sequence[BaseMessage], add_messages]
@tool
def my_tool(param: str) -> str:
"""Docstring critical for LLM!"""
return result
model_with_tools = llm.bind_tools([my_tool])def should_continue(state):
if save_tool_called:
return END
return "agent" # Continue feedback loopContributions are welcome! This workshop is designed to help network security engineers learn LangGraph effectively.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-improvement) - Make your changes
- Test thoroughly (run notebooks to verify)
- Commit your changes (
git commit -m 'Add amazing improvement') - Push to the branch (
git push origin feature/amazing-improvement) - Open a Pull Request
- Maintain workshop structure: Keep progressive complexity
- Test all changes: Ensure notebooks execute without errors
- Update documentation: Keep README and summaries current
- Follow existing patterns: Match the teaching style
- Focus on clarity: Network engineers are the audience
See CONTRIBUTING.md for detailed guidelines.
- LangGraph Documentation: python.langchain.com/docs/langgraph
- LangChain Documentation: python.langchain.com/docs
- Anthropic Claude API: docs.anthropic.com
- pan-scm-sdk: GitHub Repository
- Setup Guides: See docs/STUDENT_SETUP_GUIDE.md for detailed setup instructions
- Workshop Outline: See docs/WORKSHOP_OUTLINE.md for session planning
- SCM Examples: Reference patterns in docs/examples/ for real API structures
- Troubleshooting: See docs/TROUBLESHOOTING.md for common issues
- GitHub Issues: Report bugs or request features
- Discussions: Ask questions and share ideas
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- LangGraph by LangChain - The framework powering these AI agent workflows
- Anthropic Claude - The LLM providing intelligent automation capabilities
- Palo Alto Networks - Strata Cloud Manager platform and pan-scm-sdk
This workshop builds upon patterns and best practices from:
- LangGraph official tutorials and documentation
- LangChain community examples and guides
- Real-world network automation deployments
- Feedback from network security engineers
Calvin Remsburg (@cdot65)
Email: calvin@cdot.io
- 101: Type Annotations - TypedDict essentials
- 102: Core Concepts - State, Nodes, Edges, Graphs (streamlined)
- 103: Your First Graph - Single-node workflow
- 104: State Management - Complex multi-field states (streamlined)
- 106: Conditional Routing - Decision-making workflows
- 108: First LLM - Claude integration demo
- 110: ReAct Agents - Tools, reducers, capstone
- 105: Sequential Workflows - Deep-dive multi-node pipelines
- 107: Looping Workflows - Retry logic and pagination
- 109: Conversational Memory - Message history management
- 111: Human-in-the-Loop - Interactive collaboration
For deeper mastery, work through notebooks-extended/ versions:
- Extended notebooks 101-111 - Comprehensive coverage with additional examples
- Complete challenge exercises in extended notebooks
- Explore alternative implementation approaches
- Study production patterns and troubleshooting guides
See Extended Notebooks for when and how to use these materials.
After completing all notebooks, build your own project:
- SCM Configuration Manager: Complete CRUD operations for address objects and security rules
- Firewall Migration Assistant: AI agent that helps migrate configurations between environments
- Compliance Checker: Tool that validates security policies against best practices
- Interactive Policy Builder: Human-in-the-loop workflow for creating complex security policies
- Change Management Bot: AI agent that reviews and validates configuration changes
Ready to build AI-powered network automation?
Get Started Β· View Notebooks Β· Join Community
β If you find this workshop helpful, please star the repository! β
Made with β€οΈ for Network Security Engineers