Project 7: Network Port Security Auditor
Build a tool that inspects SELinux port labels and verifies that services bind only to allowed port types.
Quick Reference
| Attribute | Value |
|---|---|
| Difficulty | Level 2: Intermediate |
| Time Estimate | 1-2 weeks |
| Main Programming Language | Python |
| Alternative Programming Languages | Go |
| Coolness Level | Level 3 |
| Business Potential | 2 |
| Prerequisites | Projects 1-2, networking basics |
| Key Topics | port labeling, socket permissions, service domain mapping |
1. Learning Objectives
By completing this project, you will:
- Understand how SELinux labels network ports and enforces bindings.
- Map running services to their process domains and port types.
- Detect mismatches between service domains and port labels.
- Generate safe recommendations for port relabeling.
- Build a deterministic auditing report for compliance.
2. All Theory Needed (Per-Concept Breakdown)
SELinux Port Types and Port Labeling
Fundamentals
SELinux does not rely only on port numbers for network security. It labels ports with types (e.g., http_port_t, ssh_port_t) and uses those types in policy. When a process binds to a port, SELinux checks whether the process domain is allowed to bind to that port type. This means a web server running in httpd_t can bind to ports labeled http_port_t, but not to arbitrary ports unless those ports are also labeled appropriately. Understanding port types is essential for diagnosing service bind failures and building a port auditing tool.
Deep Dive into the concept
Port labeling is implemented through policy mappings that associate a protocol and port number with a type. The mapping is stored in the policy and can be managed with semanage port -l and semanage port -a/-m. SELinux checks the port type when a process calls bind(2) on a socket. The check is a TE decision: allow httpd_t http_port_t:tcp_socket name_bind; and similar. If the port number is not labeled correctly, the process will be denied, even if the Unix user has permission to bind. This is a key SELinux behavior that surprises many administrators.
Ports are not labeled dynamically; the labels are static mappings, which means non-standard ports require configuration. For example, if you run a web server on port 9000, SELinux will deny it by default because port 9000 is not labeled http_port_t. The correct fix is to label that port with semanage port -a -t http_port_t -p tcp 9000. This is a policy-level change and should be audited. Your tool will detect these cases and suggest the correct commands.
There is a security trade-off: relabeling a port expands which processes can bind to it. If you label port 9000 as http_port_t, you allow any domain permitted to bind http_port_t to use it, not just one service. This is why port labeling should be done deliberately and reviewed. Your auditor should highlight this risk and include the existing policy rule that allows the domain to bind that port type.
Your tool should also understand that ports can have multiple mappings and ranges, and that UDP/TCP are separate namespaces. It should parse semanage port -l output carefully and handle ranges (e.g., 8000-8005). It should also note when a port is unlabeled or mapped to a generic type, which can indicate a policy gap. These are the core details needed for an accurate audit.
Additional operational notes on SELinux Port Types and Port Labeling: In real systems, this concept interacts with policy versions, distribution defaults, and local overrides. Always record the exact policy version and runtime toggles when diagnosing behavior, because the same action can be allowed on one host and denied on another. When you change configuration related to this concept, capture before/after evidence (labels, logs, and outcomes) so you can justify the change, detect regressions, and roll it back if needed. Treat every tweak as a hypothesis: change one variable, re-run the same action, and compare results against a known baseline. This makes debugging repeatable and keeps your fixes defensible.
From a design perspective, treat SELinux Port Types and Port Labeling as an invariant: define what success means, which data proves it, and what failure looks like. Build tooling that supports dry-run mode and deterministic fixtures so you can validate behavior without risking production. This also makes the concept teachable to others. Finally, connect the concept to security and performance trade-offs: overly broad changes reduce security signal, while overly strict changes create operational friction. Good designs surface these trade-offs explicitly so operators can make safe decisions.
How this fit on projects
Port labeling is used in §3.2 and §3.7. It also informs P05-container-selinux-sandbox-lab.md where ports may be mapped into containers.
Definitions & key terms
- port type -> SELinux label associated with a port number
- name_bind -> permission to bind a socket
- semanage port -> tool for port label management
- port range -> contiguous set of labeled ports
Mental model diagram
httpd_t --name_bind--> http_port_t (tcp/80)
How it works (step-by-step, with invariants and failure modes)
- Process calls
bind()on a port. - SELinux resolves port number to a port type.
- Policy checks allow rules for
name_bind. - If allowed, bind succeeds; otherwise denial logged.
Invariants: port labels are static; checks are per protocol. Failure modes: unlabeled ports, mismatched port types.
Minimal concrete example
$ semanage port -l | grep http_port_t
http_port_t tcp 80, 443, 8008, 8009
Common misconceptions
- “SELinux uses port numbers only.” -> It uses port types.
- “If the service runs as root, it can bind anything.” -> SELinux still enforces.
Check-your-understanding questions
- Why does running on port 9000 cause denials by default?
- What is the risk of relabeling a port?
- How are UDP and TCP port labels different?
Check-your-understanding answers
- Because port 9000 is not labeled with the correct port type for the service.
- It expands which domains can bind to that port type.
- UDP and TCP have separate label namespaces and must be labeled separately.
Real-world applications
- Auditing web services on non-standard ports.
- Ensuring database ports are correctly labeled.
Where you’ll apply it
- This project: §3.2, §3.7, §6.2.
- Also used in: P09-ansible-selinux-hardening-role.md.
References
- “SELinux System Administration” (networking chapter)
- Red Hat SELinux Guide, port labeling
Key insights
SELinux treats ports as labeled objects; correct labeling is required for binding.
Summary
Port types control which domains can bind to which ports. This is enforced at bind time.
Homework/Exercises to practice the concept
- List port types for HTTP and SSH.
- Add a custom port to
http_port_tand verify. - Remove the port mapping and observe denial.
Solutions to the homework/exercises
semanage port -l | egrep 'http_port_t|ssh_port_t'.semanage port -a -t http_port_t -p tcp 9000.semanage port -d -t http_port_t -p tcp 9000then attempt bind.
Mapping Services to Domains and Ports
Fundamentals
To audit port usage, you must map running services to their process domains and bound ports. Tools like ss -lntp show listening sockets and their owning processes. You then map PIDs to SELinux domains using ps -eZ or /proc. This mapping allows you to check whether the domain is allowed to bind to the port type. This concept is the heart of the port auditor.
Deep Dive into the concept
Service-to-port mapping is a multi-step correlation problem. The ss or netstat tools show socket bindings, including the PID and process name. From the PID, you can retrieve the SELinux context of the process (/proc/<pid>/attr/current or ps -eZ). Then, you retrieve the port type using semanage port -l and match the protocol and port number. Finally, you can check if the domain is permitted to bind that port type using sesearch -A -s <domain> -t <port_type> -c tcp_socket -p name_bind.
This mapping is not always one-to-one. Some services use multiple processes (master/worker) with different domains. Some ports are bound by system services that spawn helpers. Your tool should use the PID from ss and treat that as the authoritative domain, not just the process name. It should also handle cases where ss does not expose PID (permission errors), in which case it should report an incomplete mapping rather than guessing.
For performance, you should cache domain lookups by PID and port type lookups by port number. Ports are relatively few, so a full map can be built quickly. The more expensive part is the policy query to check whether binding is allowed. You can optionally skip that and simply report mismatches (domain vs expected service port type), but a more complete tool uses sesearch to confirm policy allowances. This adds precision and helps distinguish between “port mislabeled” and “policy does not allow binding”.
This concept also teaches the importance of distinguishing between TCP and UDP. The same port number can have different types for different protocols. Your tool must track protocol separately in every mapping. It should also handle ephemeral ports that are bound for outgoing connections; typically your audit should focus on listening sockets (LISTEN) to avoid noise.
Operational expansion for Mapping Services to Domains and Ports: In real systems, the behavior you observe is the product of policy, labels, and runtime state. That means your investigation workflow must be repeatable. Start by documenting the exact inputs (contexts, paths, users, domains, ports, and the action attempted) and the exact outputs (audit events, error codes, and any policy query results). Then, replay the same action after each change so you can attribute cause and effect. When the concept touches multiple subsystems, isolate variables: change one label, one boolean, or one rule at a time. This reduces confusion and prevents accidental privilege creep. Use staging environments or fixtures to test fixes before deploying them widely, and always keep a rollback path ready.
To deepen understanding, connect Mapping Services to Domains and Ports to adjacent concepts: how it affects policy decisions, how it appears in logs, and how it changes operational risk. Build small verification scripts that assert the expected outcome and fail loudly if the outcome diverges. Over time, these scripts become a regression suite for your SELinux posture. Finally, treat the concept as documentation-worthy: write down the invariants it guarantees, the constraints it imposes, and the exact evidence that proves it works. This makes future debugging faster and creates a shared mental model for teams.
How this fit on projects
Port labeling is used in §3.2 and §3.7. It also informs P05-container-selinux-sandbox-lab.md where ports may be mapped into containers.
Further depth on Mapping Services to Domains and Ports: In production environments, this concept is shaped by policy versions, automation layers, and distro-specific defaults. To keep reasoning consistent, capture a minimal evidence bundle every time you analyze behavior: the policy name/version, the exact labels or contexts involved, the command that triggered the action, and the resulting audit event. If the same action yields different decisions on two hosts, treat that as a signal that a hidden variable changed (boolean state, module priority, label drift, or category range). This disciplined approach prevents trial-and-error debugging and makes your conclusions defensible.
Operationally, build a short checklist for Mapping Services to Domains and Ports: verify prerequisites, verify labels or mappings, verify policy query results, then run the action and confirm the expected audit outcome. Track metrics that reflect stability, such as the count of denials per hour, the number of unique denial keys, or the fraction of hosts in compliance. When you must change behavior, apply the smallest change that can be verified (label fix before boolean, boolean before policy). Document the rollback path and include a post-change validation step so the system returns to a known-good state.
Definitions & key terms
- port type -> SELinux label associated with a port number
- name_bind -> permission to bind a socket
- semanage port -> tool for port label management
- port range -> contiguous set of labeled ports
Mental model diagram
httpd_t --name_bind--> http_port_t (tcp/80)
How it works (step-by-step, with invariants and failure modes)
- Process calls
bind()on a port. - SELinux resolves port number to a port type.
- Policy checks allow rules for
name_bind. - If allowed, bind succeeds; otherwise denial logged.
Invariants: port labels are static; checks are per protocol. Failure modes: unlabeled ports, mismatched port types.
Minimal concrete example
$ semanage port -l | grep http_port_t
http_port_t tcp 80, 443, 8008, 8009
Common misconceptions
- “SELinux uses port numbers only.” -> It uses port types.
- “If the service runs as root, it can bind anything.” -> SELinux still enforces.
Check-your-understanding questions
- Why does running on port 9000 cause denials by default?
- What is the risk of relabeling a port?
- How are UDP and TCP port labels different?
Check-your-understanding answers
- Because port 9000 is not labeled with the correct port type for the service.
- It expands which domains can bind to that port type.
- UDP and TCP have separate label namespaces and must be labeled separately.
Real-world applications
- Auditing web services on non-standard ports.
- Ensuring database ports are correctly labeled.
Where you’ll apply it
- This project: §3.2, §3.7, §6.2.
- Also used in: P09-ansible-selinux-hardening-role.md.
References
- “SELinux System Administration” (networking chapter)
- Red Hat SELinux Guide, port labeling
Key insights
SELinux treats ports as labeled objects; correct labeling is required for binding.
Summary
Port types control which domains can bind to which ports. This is enforced at bind time.
Homework/Exercises to practice the concept
- List port types for HTTP and SSH.
- Add a custom port to
http_port_tand verify. - Remove the port mapping and observe denial.
Solutions to the homework/exercises
semanage port -l | egrep 'http_port_t|ssh_port_t'.semanage port -a -t http_port_t -p tcp 9000.semanage port -d -t http_port_t -p tcp 9000then attempt bind.
Network Socket Classes and Permissions
Fundamentals
SELinux enforces permissions on socket classes, such as tcp_socket and udp_socket. Permissions like name_bind, name_connect, and accept determine whether a process can bind, connect, or accept connections. Understanding these permissions is necessary to interpret bind denials and to explain the results of your audit.
Deep Dive into the concept
Sockets are kernel objects, and SELinux treats them as distinct classes with their own permission sets. The permission name_bind controls whether a process can bind to a port. name_connect controls outgoing connections. accept controls accepting incoming connections. When a service fails to bind, the AVC log will mention name_bind on tcp_socket or udp_socket. This is the permission your tool should look for when validating policy allowances.
The socket class also matters in policy rules. A rule that allows name_bind on tcp_socket does not automatically allow the same on udp_socket. Similarly, binding and connecting are distinct. Your tool should therefore ensure it uses the correct class and permission when checking policy. If you only check port labels, you might miss cases where policy denies name_bind even though the port is labeled correctly. This is why the optional policy check via sesearch is valuable.
Another nuance is that port labeling interacts with socket class rules: the port itself has a type (e.g., http_port_t) that is used in rules for tcp_socket class. The target type is not the socket object itself but the port type. This is a unique aspect of SELinux: ports are treated as labeled objects in the network namespace. Your tool should make this explicit in reports, so users understand why a port label is the target type.
Operational expansion for heck custom services on port 9000.: In real systems, the behavior you observe is the product of policy, labels, and runtime state. That means your investigation workflow must be repeatable. Start by documenting the exact inputs (contexts, paths, users, domains, ports, and the action attempted) and the exact outputs (audit events, error codes, and any policy query results). Then, replay the same action after each change so you can attribute cause and effect. When the concept touches multiple subsystems, isolate variables: change one label, one boolean, or one rule at a time. This reduces confusion and prevents accidental privilege creep. Use staging environments or fixtures to test fixes before deploying them widely, and always keep a rollback path ready.
To deepen understanding, connect heck custom services on port 9000. to adjacent concepts: how it affects policy decisions, how it appears in logs, and how it changes operational risk. Build small verification scripts that assert the expected outcome and fail loudly if the outcome diverges. Over time, these scripts become a regression suite for your SELinux posture. Finally, treat the concept as documentation-worthy: write down the invariants it guarantees, the constraints it imposes, and the exact evidence that proves it works. This makes future debugging faster and creates a shared mental model for teams.
Supplemental note for Network Socket Classes and Permissions: ensure your documentation includes a minimal reproducible example and a known-good output snapshot. Pair this with a small checklist of preconditions and postconditions so anyone rerunning the exercise can validate the result quickly. This turns the concept into a repeatable experiment rather than a one-off intuition.
Micro note for Network Socket Classes and Permissions: capture one concrete failure case alongside the success case and explain the difference in terms of the concept’s rules. This small contrast sharpens understanding and helps future readers debug faster.
How this fit on projects
Service-to-port mapping is in §3.2 and §4.2 (components). It also relates to P02-avc-denial-analyzer-auto-fixer.md for analyzing bind denials.
Further depth on heck custom services on port 9000.: In production environments, this concept is shaped by policy versions, automation layers, and distro-specific defaults. To keep reasoning consistent, capture a minimal evidence bundle every time you analyze behavior: the policy name/version, the exact labels or contexts involved, the command that triggered the action, and the resulting audit event. If the same action yields different decisions on two hosts, treat that as a signal that a hidden variable changed (boolean state, module priority, label drift, or category range). This disciplined approach prevents trial-and-error debugging and makes your conclusions defensible.
Operationally, build a short checklist for heck custom services on port 9000.: verify prerequisites, verify labels or mappings, verify policy query results, then run the action and confirm the expected audit outcome. Track metrics that reflect stability, such as the count of denials per hour, the number of unique denial keys, or the fraction of hosts in compliance. When you must change behavior, apply the smallest change that can be verified (label fix before boolean, boolean before policy). Document the rollback path and include a post-change validation step so the system returns to a known-good state.
Final depth note on Network Socket Classes and Permissions: tie the concept back to verification. Define a single, repeatable action that proves the rule works, and capture the exact artifact that proves it (a log line, a label comparison, or a policy query). If the proof changes between runs, treat that as a defect in the workflow, not a mystery. This habit prevents subtle regressions and makes audits far easier.
Definitions & key terms
- listening socket -> server-side port binding
- PID -> process identifier
- domain mapping -> association of PID to SELinux domain
- name_bind -> permission checked for binding
Mental model diagram
ss -> PID -> ps -eZ -> domain -> semanage port -> port type
How it works (step-by-step, with invariants and failure modes)
- Query listening sockets with
ss -lntp. - Extract PID and port.
- Get process context for each PID.
- Map port to port type.
- Validate binding permission.
Invariants: PID must be known to map domain; protocol must match port type. Failure modes: missing PID due to permissions, transient processes.
Minimal concrete example
$ ss -lntp | head -3
$ ps -p <pid> -Z
Common misconceptions
- “Process name is enough to infer domain.” -> Domain can differ from name.
- “All listening sockets matter equally.” -> Focus on services, not ephemeral.
Check-your-understanding questions
- Why is PID-to-domain mapping necessary?
- How do you handle missing PID information?
- Why should you focus on LISTEN sockets?
Check-your-understanding answers
- SELinux decisions depend on domain, not process name.
- Report as unknown and skip policy checks.
- LISTEN sockets represent server bindings; others are transient.
Real-world applications
- Security audits for service exposure.
- Detecting rogue services on unlabeled ports.
Where you’ll apply it
- This project: §3.2, §3.7, §6.2.
- Also used in: P12-enterprise-selinux-security-platform.md.
References
ssand/procdocumentation- Red Hat SELinux networking guide
Key insights
Port auditing is a correlation problem: sockets, PIDs, domains, and policy must align.
Summary
Mapping services to domains and ports is necessary to validate SELinux port policy.
Homework/Exercises to practice the concept
- Map the
sshdPID to its domain and port type. - Identify one service running on a non-standard port.
- Verify whether its domain is allowed to bind that port type.
Solutions to the homework/exercises
- Use
ss -lntpandps -eZ. - Check custom services on port 9000.
- Use
sesearch -A -s <domain> -t <port_type> -c tcp_socket -p name_bind.
3. Project Specification
3.1 What You Will Build
A CLI tool named selport that audits port labels and service bindings, reporting mismatches and recommended fixes.
Included features:
- Parse
ss -lntpfor listening sockets - Map PIDs to domains
- Map ports to port types
- Check binding permissions (optional)
- Generate recommendations for relabeling
3.2 Functional Requirements
- Socket Scan: List listening sockets with PID and port.
- Domain Mapping: Map each PID to SELinux domain.
- Port Mapping: Find port type via
semanage port -l. - Mismatch Detection: Identify ports that do not match policy.
- Reporting: Output actionable recommendations.
3.3 Non-Functional Requirements
- Accuracy: Avoid false positives by matching protocol.
- Reliability: Handle missing PID info gracefully.
- Usability: Provide clear commands for fixes.
3.4 Example Usage / Output
$ selport audit
Port 80: http_port_t (httpd_t allowed)
Port 9000: unassigned (suggest label http_port_t)
3.5 Data Formats / Schemas / Protocols
JSON output schema (v1):
{
"port": 9000,
"protocol": "tcp",
"domain": "httpd_t",
"port_type": "unassigned",
"recommendation": "semanage port -a -t http_port_t -p tcp 9000"
}
3.6 Edge Cases
- Sockets without PID (permission denied)
- Ports in ranges (8000-8005)
- Multiple services on same port with reuse
3.7 Real World Outcome
3.7.1 How to Run (Copy/Paste)
./selport audit --format text
3.7.2 Golden Path Demo (Deterministic)
Use a fixture for ss output and a fixture port mapping list to produce stable results.
3.7.3 CLI Transcript (Success and Failure)
$ ./selport audit
Port 80: http_port_t (httpd_t allowed)
Exit code: 0
$ ./selport audit --port 99999
ERROR: invalid port
Exit code: 2
3.7.4 If CLI: exit codes
0success1mismatches found2invalid input
4. Solution Architecture
4.1 High-Level Design
ss -> PID -> domain -> port map -> report
4.2 Key Components
| Component | Responsibility | Key Decisions |
|---|---|---|
| Socket scanner | Parse ss output |
Filter LISTEN sockets |
| Domain mapper | PID -> context | Cache per PID |
| Port mapper | port -> type | Parse semanage output |
| Reporter | Recommendations | Deterministic ordering |
4.3 Data Structures (No Full Code)
PortRecord = {
"port": 80,
"protocol": "tcp",
"pid": 1234,
"domain": "httpd_t",
"port_type": "http_port_t"
}
4.4 Algorithm Overview
Key Algorithm: Port Audit
- Parse
ss -lntpoutput into sockets. - Map each socket to a domain.
- Resolve port type.
- Validate and report.
Complexity Analysis:
- Time: O(n) sockets
- Space: O(n)
5. Implementation Guide
5.1 Development Environment Setup
sudo dnf install -y policycoreutils-python-utils
5.2 Project Structure
selport/
├── selport/
│ ├── cli.py
│ ├── sockets.py
│ ├── domains.py
│ ├── ports.py
│ └── report.py
└── tests/
5.3 The Core Question You’re Answering
“Are my services binding only to ports allowed by policy?”
5.4 Concepts You Must Understand First
- Port types and labeling rules.
- Mapping services to domains and ports.
- Socket class permissions.
5.5 Questions to Guide Your Design
- How will you handle missing PID information?
- Should you check policy allow rules or only label mismatches?
- How will you present risk when relabeling ports?
5.6 Thinking Exercise
List five services and their expected port types. Compare to your system’s actual labels.
5.7 The Interview Questions They’ll Ask
- “How does SELinux control port access?”
- “What is
semanage portused for?” - “When should you relabel a port?”
5.8 Hints in Layers
Hint 1: Parse ss output first
Hint 2: Add port type mapping from semanage port -l
Hint 3: Add policy checks via sesearch
5.9 Books That Will Help
| Topic | Book | Chapter |
|---|---|---|
| SELinux networking | “SELinux System Administration” | Networking chapter |
| Policy rules | “SELinux by Example” | Policy chapters |
5.10 Implementation Phases
Phase 1: Foundation (3-4 days)
Goals:
- Parse sockets and map to domains.
Tasks:
- Implement
ssparser. - Map PIDs to domains.
Checkpoint: Basic list of sockets with domains.
Phase 2: Core Functionality (4-5 days)
Goals:
- Add port type mapping and mismatch detection.
Tasks:
- Parse
semanage port -l. - Compare to service domains.
Checkpoint: Mismatch report matches fixture.
Phase 3: Polish & Edge Cases (2-3 days)
Goals:
- Add recommendations and exit codes.
Tasks:
- Generate
semanage portsuggestions. - Add JSON output.
Checkpoint: Deterministic output with exit codes.
5.11 Key Implementation Decisions
| Decision | Options | Recommendation | Rationale |
|---|---|---|---|
| Port sources | ss vs /proc/net |
ss |
simpler parsing |
| Policy validation | check allow rules vs label only | optional flag | performance vs accuracy |
| Output format | text + JSON | both | automation-friendly |
6. Testing Strategy
6.1 Test Categories
| Category | Purpose | Examples |
|---|---|---|
| Unit Tests | socket parsing | ss fixture |
| Integration Tests | full audit | fixture port map |
| Edge Case Tests | missing PID | degrade gracefully |
6.2 Critical Test Cases
- Nonstandard port detected as unassigned.
- Port range mapped correctly.
- Missing PID results in warning but not failure.
6.3 Test Data
fixtures/ss.txt
fixtures/ports.txt
7. Common Pitfalls & Debugging
7.1 Frequent Mistakes
| Pitfall | Symptom | Solution |
|---|---|---|
| Ignoring protocol | Wrong port type | Track tcp/udp separately |
| Assuming one PID per port | Missing services | Handle multiple listeners |
| Not sorting output | Non-deterministic reports | Sort by port |
7.2 Debugging Strategies
- Compare
semanage port -loutput to tool mapping. - Use a single known service for debugging.
7.3 Performance Traps
- Repeated calls to
sesearchfor each port; cache results.
8. Extensions & Challenges
8.1 Beginner Extensions
- Add CSV export.
- Highlight ports not in policy.
8.2 Intermediate Extensions
- Add whitelist of allowed services.
- Integrate with systemd to show service names.
8.3 Advanced Extensions
- Add continuous monitoring mode.
- Integrate with SIEM for alerts.
9. Real-World Connections
9.1 Industry Applications
- Port compliance audits.
- Preventing shadow services on nonstandard ports.
9.2 Related Open Source Projects
- SELinux policy tools (
semanage,sesearch).
9.3 Interview Relevance
- Network security with SELinux.
- Policy reasoning for port access.
10. Resources
10.1 Essential Reading
- “SELinux System Administration” (networking)
- Red Hat SELinux Guide (ports)
10.2 Video Resources
- SELinux network policy talks
10.3 Tools & Documentation
semanage port,ss,sesearch
10.4 Related Projects in This Series
11. Self-Assessment Checklist
11.1 Understanding
- I can explain port labeling and
name_bind. - I can map PIDs to domains.
- I can justify port relabel recommendations.
11.2 Implementation
- Audit report is correct and deterministic.
- Exit codes and warnings are documented.
- JSON output matches schema.
11.3 Growth
- I can explain risk trade-offs of relabeling ports.
- I documented how to validate policy rules.
12. Submission / Completion Criteria
Minimum Viable Completion:
- List ports, domains, and port types.
Full Completion:
- Detect mismatches and suggest fixes.
Excellence (Going Above & Beyond):
- Add policy validation and continuous monitoring.
13 Additional Content Rules (Hard Requirements)
13.1 Determinism
- Use fixtures for
ssand port mappings.
13.2 Outcome Completeness
- Provide success and failure CLI demos with exit codes.
13.3 Cross-Linking
- Link to related projects where port labeling is reused.
13.4 No Placeholder Text
- All sections are fully specified.