@mokoconsulting/mcp-mokogitea-api 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/.gitattributes +94 -0
  2. package/.gitmessage +9 -0
  3. package/.mokogitea/ISSUE_TEMPLATE/adr.md +110 -0
  4. package/.mokogitea/ISSUE_TEMPLATE/bug_report.md +48 -0
  5. package/.mokogitea/ISSUE_TEMPLATE/config.yml +18 -0
  6. package/.mokogitea/ISSUE_TEMPLATE/documentation.md +52 -0
  7. package/.mokogitea/ISSUE_TEMPLATE/enterprise_support.md +85 -0
  8. package/.mokogitea/ISSUE_TEMPLATE/feature_request.md +51 -0
  9. package/.mokogitea/ISSUE_TEMPLATE/firewall-request.md +190 -0
  10. package/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md +48 -0
  11. package/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md +67 -0
  12. package/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md +49 -0
  13. package/.mokogitea/ISSUE_TEMPLATE/question.md +82 -0
  14. package/.mokogitea/ISSUE_TEMPLATE/rfc.md +126 -0
  15. package/.mokogitea/ISSUE_TEMPLATE/security.md +51 -0
  16. package/.mokogitea/ISSUE_TEMPLATE/version.md +24 -0
  17. package/.mokogitea/auto-assign.yml +76 -0
  18. package/.mokogitea/auto-dev-issue.yml +207 -0
  19. package/.mokogitea/auto-release.yml +337 -0
  20. package/.mokogitea/branch-protection.yml +251 -0
  21. package/.mokogitea/changelog-validation.yml +101 -0
  22. package/.mokogitea/codeql-analysis.yml +115 -0
  23. package/.mokogitea/copilot-agent.yml +44 -0
  24. package/.mokogitea/deploy-demo.yml +734 -0
  25. package/.mokogitea/deploy-dev.yml +700 -0
  26. package/.mokogitea/enterprise-firewall-setup.yml +758 -0
  27. package/.mokogitea/manifest.xml +25 -0
  28. package/.mokogitea/mcp-auto-release.yml +278 -0
  29. package/.mokogitea/mcp-build-test.yml +65 -0
  30. package/.mokogitea/mcp-sdk-check.yml +109 -0
  31. package/.mokogitea/mcp-tool-inventory.yml +61 -0
  32. package/.mokogitea/pr-branch-check.yml +90 -0
  33. package/.mokogitea/repository-cleanup.yml +525 -0
  34. package/.mokogitea/standards-compliance.yml +2614 -0
  35. package/.mokogitea/sync-version-on-merge.yml +133 -0
  36. package/.mokogitea/workflows/auto-assign.yml +76 -0
  37. package/.mokogitea/workflows/auto-bump.yml +66 -0
  38. package/.mokogitea/workflows/auto-dev-issue.yml +207 -0
  39. package/.mokogitea/workflows/auto-release.yml +341 -0
  40. package/.mokogitea/workflows/branch-cleanup.yml +48 -0
  41. package/.mokogitea/workflows/cascade-dev.yml +10 -0
  42. package/.mokogitea/workflows/changelog-validation.yml +101 -0
  43. package/.mokogitea/workflows/ci-generic.yml +204 -0
  44. package/.mokogitea/workflows/cleanup.yml +87 -0
  45. package/.mokogitea/workflows/codeql-analysis.yml +115 -0
  46. package/.mokogitea/workflows/copilot-agent.yml +44 -0
  47. package/.mokogitea/workflows/deploy-manual.yml +126 -0
  48. package/.mokogitea/workflows/enterprise-firewall-setup.yml +758 -0
  49. package/.mokogitea/workflows/gitleaks.yml +96 -0
  50. package/.mokogitea/workflows/issue-branch.yml +73 -0
  51. package/.mokogitea/workflows/mcp-auto-release.yml +280 -0
  52. package/.mokogitea/workflows/mcp-build-test.yml +65 -0
  53. package/.mokogitea/workflows/mcp-sdk-check.yml +109 -0
  54. package/.mokogitea/workflows/mcp-tool-inventory.yml +61 -0
  55. package/.mokogitea/workflows/notify.yml +70 -0
  56. package/.mokogitea/workflows/npm-publish.yml +51 -0
  57. package/.mokogitea/workflows/pr-check.yml +508 -0
  58. package/.mokogitea/workflows/pre-release.yml +11 -0
  59. package/.mokogitea/workflows/repo-health.yml +711 -0
  60. package/.mokogitea/workflows/repository-cleanup.yml +525 -0
  61. package/.mokogitea/workflows/security-audit.yml +82 -0
  62. package/.mokogitea/workflows/standards-compliance.yml +2614 -0
  63. package/.mokogitea/workflows/sync-version-on-merge.yml +130 -0
  64. package/.mokogitea/workflows/update-server.yml +312 -0
  65. package/CHANGELOG.md +145 -0
  66. package/CLAUDE.md +43 -0
  67. package/CONTRIBUTING.md +161 -0
  68. package/README.md +286 -0
  69. package/SECURITY.md +91 -0
  70. package/automation/ci-issue-reporter.sh +237 -0
  71. package/config.example.json +13 -0
  72. package/dist/client.d.ts +15 -0
  73. package/dist/client.js +104 -0
  74. package/dist/config.d.ts +4 -0
  75. package/dist/config.js +48 -0
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.js +1119 -0
  78. package/dist/types.d.ts +20 -0
  79. package/dist/types.js +16 -0
  80. package/package.json +34 -0
  81. package/scripts/setup.mjs +40 -0
  82. package/src/client.ts +120 -0
  83. package/src/config.ts +58 -0
  84. package/src/index.ts +1712 -0
  85. package/src/types.ts +37 -0
  86. package/tsconfig.json +19 -0
@@ -0,0 +1,758 @@
1
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ #
3
+ # This file is part of a Moko Consulting project.
4
+ #
5
+ # SPDX-License-Identifier: GPL-3.0-or-later
6
+ #
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
19
+
20
+ # FILE INFORMATION
21
+ # DEFGROUP: GitHub.Workflow
22
+ # INGROUP: MokoStandards.Firewall
23
+ # REPO: https://github.com/mokoconsulting-tech/MokoStandards
24
+ # PATH: /templates/workflows/shared/enterprise-firewall-setup.yml.template
25
+ # VERSION: 04.06.00
26
+ # BRIEF: Enterprise firewall configuration — generates outbound allow-rules including SFTP deployment server
27
+ # NOTE: Reads DEV_FTP_HOST / DEV_FTP_PORT variables to include SFTP egress rules alongside HTTPS rules.
28
+
29
+ name: "MCP: Enterprise Firewall"
30
+
31
+ # This workflow provides firewall configuration guidance for enterprise-ready sites
32
+ # It generates firewall rules for allowing outbound access to trusted domains
33
+ # including license providers, documentation sources, package registries,
34
+ # and the SFTP deployment server (DEV_FTP_HOST / DEV_FTP_PORT).
35
+ #
36
+ # Runs automatically when:
37
+ # - Coding agent workflows are triggered (pull requests with copilot/ prefix)
38
+ # - Manual workflow dispatch for custom configurations
39
+
40
+ on:
41
+ workflow_dispatch:
42
+ inputs:
43
+ firewall_type:
44
+ description: 'Target firewall type'
45
+ required: true
46
+ type: choice
47
+ options:
48
+ - 'iptables'
49
+ - 'ufw'
50
+ - 'firewalld'
51
+ - 'aws-security-group'
52
+ - 'azure-nsg'
53
+ - 'gcp-firewall'
54
+ - 'cloudflare'
55
+ - 'all'
56
+ default: 'all'
57
+ output_format:
58
+ description: 'Output format'
59
+ required: true
60
+ type: choice
61
+ options:
62
+ - 'shell-script'
63
+ - 'json'
64
+ - 'yaml'
65
+ - 'markdown'
66
+ - 'all'
67
+ default: 'markdown'
68
+
69
+ # Auto-run when coding agent creates or updates PRs
70
+ pull_request:
71
+ branches:
72
+ - 'copilot/**'
73
+ - 'agent/**'
74
+ types: [opened, synchronize, reopened]
75
+
76
+ # Auto-run on push to coding agent branches
77
+ push:
78
+ branches:
79
+ - 'copilot/**'
80
+ - 'agent/**'
81
+
82
+ permissions:
83
+ contents: read
84
+ actions: read
85
+
86
+ jobs:
87
+ generate-firewall-rules:
88
+ name: Generate Firewall Rules
89
+ runs-on: ubuntu-latest
90
+
91
+ steps:
92
+ - name: Checkout repository
93
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
94
+
95
+ - name: Set up Python
96
+ uses: actions/setup-python@v6
97
+ with:
98
+ python-version: '3.11'
99
+
100
+ - name: Apply Firewall Rules to Runner (Auto-run only)
101
+ if: github.event_name != 'workflow_dispatch'
102
+ env:
103
+ DEV_FTP_HOST: ${{ vars.DEV_FTP_HOST }}
104
+ DEV_FTP_PORT: ${{ vars.DEV_FTP_PORT }}
105
+ run: |
106
+ echo "🔥 Applying firewall rules for coding agent environment..."
107
+ echo ""
108
+ echo "This step ensures the GitHub Actions runner can access trusted domains"
109
+ echo "including license providers, package registries, and documentation sources."
110
+ echo ""
111
+
112
+ # Note: GitHub Actions runners are ephemeral and run in controlled environments
113
+ # This step documents what domains are being accessed during the workflow
114
+ # Actual firewall configuration is managed by GitHub
115
+
116
+ cat > /tmp/trusted-domains.txt << 'EOF'
117
+ # Trusted domains for coding agent environment
118
+ # License Providers
119
+ www.gnu.org
120
+ opensource.org
121
+ choosealicense.com
122
+ spdx.org
123
+ creativecommons.org
124
+ apache.org
125
+ fsf.org
126
+
127
+ # Documentation & Standards
128
+ semver.org
129
+ keepachangelog.com
130
+ conventionalcommits.org
131
+
132
+ # GitHub & Related
133
+ github.com
134
+ api.github.com
135
+ docs.github.com
136
+ raw.githubusercontent.com
137
+ ghcr.io
138
+
139
+ # Package Registries
140
+ npmjs.com
141
+ registry.npmjs.org
142
+ pypi.org
143
+ files.pythonhosted.org
144
+ packagist.org
145
+ repo.packagist.org
146
+ rubygems.org
147
+
148
+ # Platform-Specific
149
+ joomla.org
150
+ downloads.joomla.org
151
+ docs.joomla.org
152
+ php.net
153
+ getcomposer.org
154
+ dolibarr.org
155
+ wiki.dolibarr.org
156
+ docs.dolibarr.org
157
+
158
+ # Moko Consulting
159
+ mokoconsulting.tech
160
+
161
+ # SFTP Deployment Server (DEV_FTP_HOST)
162
+ ${DEV_FTP_HOST:-<not configured>}
163
+
164
+ # Google Services
165
+ drive.google.com
166
+ docs.google.com
167
+ sheets.google.com
168
+ accounts.google.com
169
+ storage.googleapis.com
170
+ fonts.googleapis.com
171
+ fonts.gstatic.com
172
+
173
+ # GitHub Extended
174
+ upload.github.com
175
+ objects.githubusercontent.com
176
+ user-images.githubusercontent.com
177
+ codeload.github.com
178
+ pkg.github.com
179
+
180
+ # Developer Reference
181
+ developer.mozilla.org
182
+ stackoverflow.com
183
+ git-scm.com
184
+
185
+ # CDN & Infrastructure
186
+ cdn.jsdelivr.net
187
+ unpkg.com
188
+ cdnjs.cloudflare.com
189
+ img.shields.io
190
+
191
+ # Container Registries
192
+ hub.docker.com
193
+ registry-1.docker.io
194
+
195
+ # CI & Code Quality
196
+ codecov.io
197
+ sonarcloud.io
198
+
199
+ # Terraform & Infrastructure
200
+ registry.terraform.io
201
+ releases.hashicorp.com
202
+ checkpoint-api.hashicorp.com
203
+ EOF
204
+
205
+ echo "✓ Trusted domains documented for this runner"
206
+ echo "✓ GitHub Actions runners have network access to these domains"
207
+ echo ""
208
+
209
+ # Test connectivity to key domains
210
+ echo "Testing connectivity to key domains..."
211
+ for domain in "github.com" "www.gnu.org" "npmjs.com" "pypi.org"; do
212
+ if curl -s --max-time 3 -o /dev/null -w "%{http_code}" "https://$domain" | grep -q "200\|301\|302"; then
213
+ echo " ✓ $domain is accessible"
214
+ else
215
+ echo " ⚠️ $domain connectivity check failed (may be expected)"
216
+ fi
217
+ done
218
+
219
+ # Test SFTP server connectivity (TCP port check)
220
+ SFTP_HOST="${DEV_FTP_HOST:-}"
221
+ SFTP_PORT="${DEV_FTP_PORT:-22}"
222
+ if [ -n "$SFTP_HOST" ]; then
223
+ # Strip any embedded :port suffix
224
+ SFTP_HOST="${SFTP_HOST%%:*}"
225
+ echo ""
226
+ echo "Testing SFTP deployment server connectivity..."
227
+ if timeout 5 bash -c "echo >/dev/tcp/${SFTP_HOST}/${SFTP_PORT}" 2>/dev/null; then
228
+ echo " ✓ SFTP server ${SFTP_HOST}:${SFTP_PORT} is reachable"
229
+ else
230
+ echo " ⚠️ SFTP server ${SFTP_HOST}:${SFTP_PORT} is not reachable from runner (firewall rule needed)"
231
+ fi
232
+ else
233
+ echo ""
234
+ echo " ℹ️ DEV_FTP_HOST not configured — skipping SFTP connectivity check"
235
+ fi
236
+
237
+ - name: Generate Firewall Configuration
238
+ id: generate
239
+ env:
240
+ DEV_FTP_HOST: ${{ vars.DEV_FTP_HOST }}
241
+ DEV_FTP_PORT: ${{ vars.DEV_FTP_PORT }}
242
+ run: |
243
+ cat > generate_firewall_config.py << 'PYTHON_EOF'
244
+ #!/usr/bin/env python3
245
+ """
246
+ Enterprise Firewall Configuration Generator
247
+
248
+ Generates firewall rules for enterprise-ready deployments allowing
249
+ access to trusted domains including license providers, documentation
250
+ sources, package registries, and platform-specific sites.
251
+ """
252
+
253
+ import json
254
+ import os
255
+ import yaml
256
+ import sys
257
+ from typing import List, Dict
258
+
259
+ # SFTP deployment server from org variables
260
+ _sftp_host_raw = os.environ.get("DEV_FTP_HOST", "").strip()
261
+ _sftp_port = os.environ.get("DEV_FTP_PORT", "").strip() or "22"
262
+ # Strip embedded :port suffix if present
263
+ _sftp_host = _sftp_host_raw.split(":")[0] if _sftp_host_raw else ""
264
+ if ":" in _sftp_host_raw and not _sftp_port:
265
+ _sftp_port = _sftp_host_raw.split(":")[1]
266
+
267
+ SFTP_HOST = _sftp_host
268
+ SFTP_PORT = int(_sftp_port) if _sftp_port.isdigit() else 22
269
+
270
+ # Trusted domains from .github/copilot.yml
271
+ TRUSTED_DOMAINS = {
272
+ "license_providers": [
273
+ "www.gnu.org",
274
+ "opensource.org",
275
+ "choosealicense.com",
276
+ "spdx.org",
277
+ "creativecommons.org",
278
+ "apache.org",
279
+ "fsf.org",
280
+ ],
281
+ "documentation_standards": [
282
+ "semver.org",
283
+ "keepachangelog.com",
284
+ "conventionalcommits.org",
285
+ ],
286
+ "github_related": [
287
+ "github.com",
288
+ "api.github.com",
289
+ "docs.github.com",
290
+ "raw.githubusercontent.com",
291
+ "ghcr.io",
292
+ ],
293
+ "package_registries": [
294
+ "npmjs.com",
295
+ "registry.npmjs.org",
296
+ "pypi.org",
297
+ "files.pythonhosted.org",
298
+ "packagist.org",
299
+ "repo.packagist.org",
300
+ "rubygems.org",
301
+ ],
302
+ "standards_organizations": [
303
+ "json-schema.org",
304
+ "w3.org",
305
+ "ietf.org",
306
+ ],
307
+ "platform_specific": [
308
+ "joomla.org",
309
+ "downloads.joomla.org",
310
+ "docs.joomla.org",
311
+ "php.net",
312
+ "getcomposer.org",
313
+ "dolibarr.org",
314
+ "wiki.dolibarr.org",
315
+ "docs.dolibarr.org",
316
+ ],
317
+ "moko_consulting": [
318
+ "mokoconsulting.tech",
319
+ ],
320
+ "google_services": [
321
+ "drive.google.com",
322
+ "docs.google.com",
323
+ "sheets.google.com",
324
+ "accounts.google.com",
325
+ "storage.googleapis.com",
326
+ "fonts.googleapis.com",
327
+ "fonts.gstatic.com",
328
+ ],
329
+ "github_extended": [
330
+ "upload.github.com",
331
+ "objects.githubusercontent.com",
332
+ "user-images.githubusercontent.com",
333
+ "codeload.github.com",
334
+ "pkg.github.com",
335
+ ],
336
+ "developer_reference": [
337
+ "developer.mozilla.org",
338
+ "stackoverflow.com",
339
+ "git-scm.com",
340
+ ],
341
+ "cdn_and_infrastructure": [
342
+ "cdn.jsdelivr.net",
343
+ "unpkg.com",
344
+ "cdnjs.cloudflare.com",
345
+ "img.shields.io",
346
+ ],
347
+ "container_registries": [
348
+ "hub.docker.com",
349
+ "registry-1.docker.io",
350
+ ],
351
+ "ci_code_quality": [
352
+ "codecov.io",
353
+ "sonarcloud.io",
354
+ ],
355
+ "terraform_infrastructure": [
356
+ "registry.terraform.io",
357
+ "releases.hashicorp.com",
358
+ "checkpoint-api.hashicorp.com",
359
+ ],
360
+ }
361
+
362
+ # Inject SFTP deployment server as a separate category (port 22, not 443)
363
+ if SFTP_HOST:
364
+ TRUSTED_DOMAINS["sftp_deployment_server"] = [SFTP_HOST]
365
+ print(f"ℹ️ SFTP deployment server: {SFTP_HOST}:{SFTP_PORT}")
366
+
367
+ def generate_sftp_iptables_rules(host: str, port: int) -> str:
368
+ """Generate iptables rules specifically for SFTP egress"""
369
+ return (
370
+ f"# Allow SFTP to deployment server {host}:{port}\n"
371
+ f"iptables -A OUTPUT -p tcp -d $(dig +short {host} | head -1)"
372
+ f" --dport {port} -j ACCEPT # SFTP deploy\n"
373
+ )
374
+
375
+ def generate_sftp_ufw_rules(host: str, port: int) -> str:
376
+ """Generate UFW rules for SFTP egress"""
377
+ return (
378
+ f"# Allow SFTP to deployment server\n"
379
+ f"ufw allow out to $(dig +short {host} | head -1)"
380
+ f" port {port} proto tcp comment 'SFTP deploy to {host}'\n"
381
+ )
382
+
383
+ def generate_sftp_firewalld_rules(host: str, port: int) -> str:
384
+ """Generate firewalld rules for SFTP egress"""
385
+ return (
386
+ f"# Allow SFTP to deployment server\n"
387
+ f"firewall-cmd --permanent --add-rich-rule='"
388
+ f"rule family=ipv4 destination address=$(dig +short {host} | head -1)"
389
+ f" port port={port} protocol=tcp accept' # SFTP deploy\n"
390
+ )
391
+
392
+ def generate_iptables_rules(domains: List[str]) -> str:
393
+ """Generate iptables firewall rules"""
394
+ rules = ["#!/bin/bash", "", "# Enterprise Firewall Rules - iptables", ""]
395
+ rules.append("# Allow outbound HTTPS to trusted domains")
396
+ rules.append("")
397
+
398
+ for domain in domains:
399
+ rules.append(f"# Allow {domain}")
400
+ rules.append(f"iptables -A OUTPUT -p tcp -d $(dig +short {domain} | head -1) --dport 443 -j ACCEPT")
401
+
402
+ rules.append("")
403
+ rules.append("# Allow DNS lookups")
404
+ rules.append("iptables -A OUTPUT -p udp --dport 53 -j ACCEPT")
405
+ rules.append("iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT")
406
+
407
+ return "\n".join(rules)
408
+
409
+ def generate_ufw_rules(domains: List[str]) -> str:
410
+ """Generate UFW firewall rules"""
411
+ rules = ["#!/bin/bash", "", "# Enterprise Firewall Rules - UFW", ""]
412
+ rules.append("# Allow outbound HTTPS to trusted domains")
413
+ rules.append("")
414
+
415
+ for domain in domains:
416
+ rules.append(f"# Allow {domain}")
417
+ rules.append(f"ufw allow out to $(dig +short {domain} | head -1) port 443 proto tcp comment 'Allow {domain}'")
418
+
419
+ rules.append("")
420
+ rules.append("# Allow DNS")
421
+ rules.append("ufw allow out 53/udp comment 'Allow DNS UDP'")
422
+ rules.append("ufw allow out 53/tcp comment 'Allow DNS TCP'")
423
+
424
+ return "\n".join(rules)
425
+
426
+ def generate_firewalld_rules(domains: List[str]) -> str:
427
+ """Generate firewalld rules"""
428
+ rules = ["#!/bin/bash", "", "# Enterprise Firewall Rules - firewalld", ""]
429
+ rules.append("# Add trusted domains to firewall")
430
+ rules.append("")
431
+
432
+ for domain in domains:
433
+ rules.append(f"# Allow {domain}")
434
+ rules.append(f"firewall-cmd --permanent --add-rich-rule='rule family=ipv4 destination address=$(dig +short {domain} | head -1) port port=443 protocol=tcp accept'")
435
+
436
+ rules.append("")
437
+ rules.append("# Reload firewall")
438
+ rules.append("firewall-cmd --reload")
439
+
440
+ return "\n".join(rules)
441
+
442
+ def generate_aws_security_group(domains: List[str]) -> Dict:
443
+ """Generate AWS Security Group rules (JSON format)"""
444
+ rules = {
445
+ "SecurityGroupRules": {
446
+ "Egress": []
447
+ }
448
+ }
449
+
450
+ for domain in domains:
451
+ rules["SecurityGroupRules"]["Egress"].append({
452
+ "Description": f"Allow HTTPS to {domain}",
453
+ "IpProtocol": "tcp",
454
+ "FromPort": 443,
455
+ "ToPort": 443,
456
+ "CidrIp": "0.0.0.0/0", # In practice, resolve to specific IPs
457
+ "Tags": [{
458
+ "Key": "Domain",
459
+ "Value": domain
460
+ }]
461
+ })
462
+
463
+ # Add DNS
464
+ rules["SecurityGroupRules"]["Egress"].append({
465
+ "Description": "Allow DNS",
466
+ "IpProtocol": "udp",
467
+ "FromPort": 53,
468
+ "ToPort": 53,
469
+ "CidrIp": "0.0.0.0/0"
470
+ })
471
+
472
+ return rules
473
+
474
+ def generate_markdown_documentation(domains_by_category: Dict[str, List[str]]) -> str:
475
+ """Generate markdown documentation"""
476
+ md = ["# Enterprise Firewall Configuration Guide", ""]
477
+ md.append("## Overview")
478
+ md.append("")
479
+ md.append("This document provides firewall configuration guidance for enterprise-ready deployments.")
480
+ md.append("It lists trusted domains that should be whitelisted for outbound access to ensure")
481
+ md.append("proper functionality of license validation, package management, and documentation access.")
482
+ md.append("")
483
+
484
+ md.append("## Trusted Domains by Category")
485
+ md.append("")
486
+
487
+ all_domains = []
488
+ for category, domains in domains_by_category.items():
489
+ category_name = category.replace("_", " ").title()
490
+ md.append(f"### {category_name}")
491
+ md.append("")
492
+ md.append("| Domain | Purpose |")
493
+ md.append("|--------|---------|")
494
+
495
+ for domain in domains:
496
+ all_domains.append(domain)
497
+ purpose = get_domain_purpose(domain)
498
+ md.append(f"| `{domain}` | {purpose} |")
499
+
500
+ md.append("")
501
+
502
+ md.append("## Implementation Examples")
503
+ md.append("")
504
+
505
+ md.append("### iptables Example")
506
+ md.append("")
507
+ md.append("```bash")
508
+ md.append("# Allow HTTPS to trusted domain")
509
+ md.append(f"iptables -A OUTPUT -p tcp -d $(dig +short {all_domains[0]}) --dport 443 -j ACCEPT")
510
+ md.append("```")
511
+ md.append("")
512
+
513
+ md.append("### UFW Example")
514
+ md.append("")
515
+ md.append("```bash")
516
+ md.append("# Allow HTTPS to trusted domain")
517
+ md.append(f"ufw allow out to {all_domains[0]} port 443 proto tcp")
518
+ md.append("```")
519
+ md.append("")
520
+
521
+ md.append("### AWS Security Group Example")
522
+ md.append("")
523
+ md.append("```json")
524
+ md.append("{")
525
+ md.append(' "IpPermissions": [{')
526
+ md.append(' "IpProtocol": "tcp",')
527
+ md.append(' "FromPort": 443,')
528
+ md.append(' "ToPort": 443,')
529
+ md.append(' "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "HTTPS to trusted domains"}]')
530
+ md.append(" }]")
531
+ md.append("}")
532
+ md.append("```")
533
+ md.append("")
534
+
535
+ md.append("## Ports Required")
536
+ md.append("")
537
+ md.append("| Port | Protocol | Purpose |")
538
+ md.append("|------|----------|---------|")
539
+ md.append("| 443 | TCP | HTTPS (secure web access) |")
540
+ md.append("| 80 | TCP | HTTP (redirects to HTTPS) |")
541
+ md.append("| 53 | UDP/TCP | DNS resolution |")
542
+ md.append("")
543
+
544
+ md.append("## Security Considerations")
545
+ md.append("")
546
+ md.append("1. **DNS Resolution**: Ensure DNS queries are allowed (port 53 UDP/TCP)")
547
+ md.append("2. **Certificate Validation**: HTTPS requires ability to reach certificate authorities")
548
+ md.append("3. **Dynamic IPs**: Some domains use CDNs with dynamic IPs - consider using FQDNs in rules")
549
+ md.append("4. **Regular Updates**: Review and update whitelist as services change")
550
+ md.append("5. **Logging**: Enable logging for blocked connections to identify missing rules")
551
+ md.append("")
552
+
553
+ md.append("## Compliance Notes")
554
+ md.append("")
555
+ md.append("- All listed domains provide read-only access to public information")
556
+ md.append("- License providers enable GPL compliance verification")
557
+ md.append("- Package registries support dependency security scanning")
558
+ md.append("- No authentication credentials are transmitted to these domains")
559
+ md.append("")
560
+
561
+ return "\n".join(md)
562
+
563
+ def get_domain_purpose(domain: str) -> str:
564
+ """Get human-readable purpose for a domain"""
565
+ purposes = {
566
+ "www.gnu.org": "GNU licenses and documentation",
567
+ "opensource.org": "Open Source Initiative resources",
568
+ "choosealicense.com": "GitHub license selection tool",
569
+ "spdx.org": "Software Package Data Exchange identifiers",
570
+ "creativecommons.org": "Creative Commons licenses",
571
+ "apache.org": "Apache Software Foundation licenses",
572
+ "fsf.org": "Free Software Foundation resources",
573
+ "semver.org": "Semantic versioning specification",
574
+ "keepachangelog.com": "Changelog format standards",
575
+ "conventionalcommits.org": "Commit message conventions",
576
+ "github.com": "GitHub platform access",
577
+ "api.github.com": "GitHub API access",
578
+ "docs.github.com": "GitHub documentation",
579
+ "raw.githubusercontent.com": "GitHub raw content access",
580
+ "npmjs.com": "npm package registry",
581
+ "pypi.org": "Python Package Index",
582
+ "packagist.org": "PHP Composer package registry",
583
+ "rubygems.org": "Ruby gems registry",
584
+ "joomla.org": "Joomla CMS platform",
585
+ "php.net": "PHP documentation and downloads",
586
+ "dolibarr.org": "Dolibarr ERP/CRM platform",
587
+ }
588
+ return purposes.get(domain, "Trusted resource")
589
+
590
+ def main():
591
+ # Use inputs if provided (manual dispatch), otherwise use defaults (auto-run)
592
+ firewall_type = "${{ github.event.inputs.firewall_type }}" or "all"
593
+ output_format = "${{ github.event.inputs.output_format }}" or "markdown"
594
+
595
+ print(f"Running in {'manual' if '${{ github.event.inputs.firewall_type }}' else 'automatic'} mode")
596
+ print(f"Firewall type: {firewall_type}")
597
+ print(f"Output format: {output_format}")
598
+ print("")
599
+
600
+ # Collect all domains
601
+ all_domains = []
602
+ for domains in TRUSTED_DOMAINS.values():
603
+ all_domains.extend(domains)
604
+
605
+ # Remove duplicates and sort
606
+ all_domains = sorted(set(all_domains))
607
+
608
+ print(f"Generating firewall rules for {len(all_domains)} trusted domains...")
609
+ print("")
610
+
611
+ # Exclude SFTP server from HTTPS rule generation (different port)
612
+ https_domains = [d for d in all_domains if d != SFTP_HOST]
613
+
614
+ # Generate based on firewall type
615
+ if firewall_type in ["iptables", "all"]:
616
+ rules = generate_iptables_rules(https_domains)
617
+ if SFTP_HOST:
618
+ rules += "\n# ── SFTP Deployment Server ──────────────────────────────\n"
619
+ rules += generate_sftp_iptables_rules(SFTP_HOST, SFTP_PORT)
620
+ with open("firewall-rules-iptables.sh", "w") as f:
621
+ f.write(rules)
622
+ print("✓ Generated iptables rules: firewall-rules-iptables.sh")
623
+
624
+ if firewall_type in ["ufw", "all"]:
625
+ rules = generate_ufw_rules(https_domains)
626
+ if SFTP_HOST:
627
+ rules += "\n# ── SFTP Deployment Server ──────────────────────────────\n"
628
+ rules += generate_sftp_ufw_rules(SFTP_HOST, SFTP_PORT)
629
+ with open("firewall-rules-ufw.sh", "w") as f:
630
+ f.write(rules)
631
+ print("✓ Generated UFW rules: firewall-rules-ufw.sh")
632
+
633
+ if firewall_type in ["firewalld", "all"]:
634
+ rules = generate_firewalld_rules(https_domains)
635
+ if SFTP_HOST:
636
+ rules += "\n# ── SFTP Deployment Server ──────────────────────────────\n"
637
+ rules += generate_sftp_firewalld_rules(SFTP_HOST, SFTP_PORT)
638
+ with open("firewall-rules-firewalld.sh", "w") as f:
639
+ f.write(rules)
640
+ print("✓ Generated firewalld rules: firewall-rules-firewalld.sh")
641
+
642
+ if firewall_type in ["aws-security-group", "all"]:
643
+ rules = generate_aws_security_group(all_domains)
644
+ with open("firewall-rules-aws-sg.json", "w") as f:
645
+ json.dump(rules, f, indent=2)
646
+ print("✓ Generated AWS Security Group rules: firewall-rules-aws-sg.json")
647
+
648
+ if output_format in ["yaml", "all"]:
649
+ with open("trusted-domains.yml", "w") as f:
650
+ yaml.dump(TRUSTED_DOMAINS, f, default_flow_style=False)
651
+ print("✓ Generated YAML domain list: trusted-domains.yml")
652
+
653
+ if output_format in ["json", "all"]:
654
+ with open("trusted-domains.json", "w") as f:
655
+ json.dump(TRUSTED_DOMAINS, f, indent=2)
656
+ print("✓ Generated JSON domain list: trusted-domains.json")
657
+
658
+ if output_format in ["markdown", "all"]:
659
+ md = generate_markdown_documentation(TRUSTED_DOMAINS)
660
+ with open("FIREWALL_CONFIGURATION.md", "w") as f:
661
+ f.write(md)
662
+ print("✓ Generated documentation: FIREWALL_CONFIGURATION.md")
663
+
664
+ print("")
665
+ print("Domain Categories:")
666
+ for category, domains in TRUSTED_DOMAINS.items():
667
+ print(f" - {category}: {len(domains)} domains")
668
+
669
+ print("")
670
+ print("Total unique domains: ", len(all_domains))
671
+
672
+ if __name__ == "__main__":
673
+ main()
674
+ PYTHON_EOF
675
+
676
+ chmod +x generate_firewall_config.py
677
+ pip install PyYAML
678
+ python3 generate_firewall_config.py
679
+
680
+ - name: Upload Firewall Configuration Artifacts
681
+ uses: actions/upload-artifact@v6
682
+ with:
683
+ name: firewall-configurations
684
+ path: |
685
+ firewall-rules-*.sh
686
+ firewall-rules-*.json
687
+ trusted-domains.*
688
+ FIREWALL_CONFIGURATION.md
689
+ retention-days: 90
690
+
691
+ - name: Display Summary
692
+ run: |
693
+ echo "## Firewall Configuration" >> $GITHUB_STEP_SUMMARY
694
+ echo "" >> $GITHUB_STEP_SUMMARY
695
+
696
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
697
+ echo "**Mode**: Manual Execution" >> $GITHUB_STEP_SUMMARY
698
+ echo "" >> $GITHUB_STEP_SUMMARY
699
+ echo "Firewall rules have been generated for enterprise-ready deployments." >> $GITHUB_STEP_SUMMARY
700
+ else
701
+ echo "**Mode**: Automatic Execution (Coding Agent Active)" >> $GITHUB_STEP_SUMMARY
702
+ echo "" >> $GITHUB_STEP_SUMMARY
703
+ echo "This workflow ran automatically because a coding agent (GitHub Copilot) is active." >> $GITHUB_STEP_SUMMARY
704
+ echo "Firewall configuration has been validated for the coding agent environment." >> $GITHUB_STEP_SUMMARY
705
+ fi
706
+
707
+ echo "" >> $GITHUB_STEP_SUMMARY
708
+ echo "### Files Generated" >> $GITHUB_STEP_SUMMARY
709
+ echo "" >> $GITHUB_STEP_SUMMARY
710
+ if ls firewall-rules-* trusted-domains.* FIREWALL_CONFIGURATION.md 2>/dev/null; then
711
+ ls -lh firewall-rules-* trusted-domains.* FIREWALL_CONFIGURATION.md 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' >> $GITHUB_STEP_SUMMARY
712
+ else
713
+ echo "- Documentation generated" >> $GITHUB_STEP_SUMMARY
714
+ fi
715
+ echo "" >> $GITHUB_STEP_SUMMARY
716
+
717
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
718
+ echo "### Download Artifacts" >> $GITHUB_STEP_SUMMARY
719
+ echo "" >> $GITHUB_STEP_SUMMARY
720
+ echo "Download the generated firewall configurations from the workflow artifacts." >> $GITHUB_STEP_SUMMARY
721
+ else
722
+ echo "### Trusted Domains Active" >> $GITHUB_STEP_SUMMARY
723
+ echo "" >> $GITHUB_STEP_SUMMARY
724
+ echo "The coding agent has access to:" >> $GITHUB_STEP_SUMMARY
725
+ echo "- License providers (GPL, OSI, SPDX, Apache, etc.)" >> $GITHUB_STEP_SUMMARY
726
+ echo "- Package registries (npm, PyPI, Packagist, RubyGems)" >> $GITHUB_STEP_SUMMARY
727
+ echo "- Documentation sources (GitHub, Joomla, Dolibarr, PHP)" >> $GITHUB_STEP_SUMMARY
728
+ echo "- Standards organizations (W3C, IETF, JSON Schema)" >> $GITHUB_STEP_SUMMARY
729
+ fi
730
+
731
+ # Usage Instructions:
732
+ #
733
+ # This workflow runs in two modes:
734
+ #
735
+ # 1. AUTOMATIC MODE (Coding Agent):
736
+ # - Triggers when coding agent branches (copilot/**, agent/**) are pushed or PR'd
737
+ # - Validates firewall configuration for the coding agent environment
738
+ # - Documents accessible domains for compliance
739
+ # - Ensures license sources and package registries are available
740
+ #
741
+ # 2. MANUAL MODE (Enterprise Configuration):
742
+ # - Manually trigger from the Actions tab
743
+ # - Select desired firewall type and output format
744
+ # - Download generated artifacts
745
+ # - Apply firewall rules to your enterprise environment
746
+ #
747
+ # Configuration:
748
+ # - Trusted domains are sourced from .github/copilot.yml
749
+ # - Modify copilot.yml to add/remove trusted domains
750
+ # - Changes automatically propagate to firewall rules
751
+ #
752
+ # Important Notes:
753
+ # - Review generated rules before applying to production
754
+ # - Some domains may use CDNs with dynamic IPs
755
+ # - Consider using FQDN-based rules where supported
756
+ # - Test thoroughly in staging environment first
757
+ # - Monitor logs for blocked connections
758
+ # - Update rules as domains/services change