Includes: API (Express/TypeScript), Astro site, Python workers, document generators, FCC compliance tools, Canada CRTC formation, Ansible infrastructure, and deployment scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
258 lines
11 KiB
Python
258 lines
11 KiB
Python
"""
|
|
Generate the CPNI Procedure Statement — internal / customer-facing policy.
|
|
|
|
This is **not** the annual ECFS certification letter (see
|
|
``cpni_cert_letter_generator.py`` for that). This is the 10-section policy
|
|
document every carrier must maintain and provide to customers under
|
|
47 CFR § 64.2008 (annual notice). Every example carrier in
|
|
``docs/examplefilings/`` has one of these alongside their CPNI cert —
|
|
Cloud One PBX, Fortel, VoIPFlo, Engage, Syntracom, Zingo, TIP Systems —
|
|
all using this exact 10-section outline.
|
|
|
|
Canonical section outline:
|
|
|
|
1. Purpose
|
|
2. Definition of CPNI
|
|
3. Employee Training and Compliance
|
|
4. Customer Authentication and Access Control
|
|
5. Use of CPNI
|
|
6. Customer Rights and Notification
|
|
7. CPNI Breach Notification and Reporting
|
|
8. Record Keeping and Audits
|
|
9. Enforcement and Penalties
|
|
10. Contact Information
|
|
|
|
Footer: Effective Date / Signatory / Reviewed By / Next Review Date.
|
|
|
|
Usage:
|
|
from scripts.document_gen.templates.cpni_procedure_statement_generator import (
|
|
generate_cpni_procedure_statement,
|
|
)
|
|
path = generate_cpni_procedure_statement(
|
|
entity_name="Falcon Broadband LLC",
|
|
entity_abbr="FBL",
|
|
support_email="support@falconbroadband.com",
|
|
website="https://falconbroadband.com",
|
|
signatory_name="Jane Doe",
|
|
signatory_title="President",
|
|
output_path="/tmp/cpni_policy.docx",
|
|
)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from datetime import date, datetime
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
LOG = logging.getLogger("document_gen.cpni_policy")
|
|
|
|
try:
|
|
from docx import Document
|
|
from docx.shared import Pt, Inches, RGBColor
|
|
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
|
except ImportError:
|
|
LOG.warning("python-docx not installed — CPNI policy generation unavailable")
|
|
Document = None # type: ignore[assignment, misc]
|
|
|
|
NAVY = RGBColor(0x1A, 0x27, 0x44) if Document else None
|
|
BODY_SIZE = Pt(11) if Document else None
|
|
HEADING_SIZE = Pt(13) if Document else None
|
|
PARA_AFTER = Pt(6) if Document else None
|
|
|
|
|
|
def _heading(doc, text: str) -> None:
|
|
p = doc.add_paragraph()
|
|
p.paragraph_format.space_before = Pt(12)
|
|
p.paragraph_format.space_after = Pt(4)
|
|
run = p.add_run(text)
|
|
run.bold = True
|
|
run.font.size = HEADING_SIZE
|
|
run.font.color.rgb = NAVY
|
|
|
|
|
|
def _body(doc, text: str, bold: bool = False) -> None:
|
|
p = doc.add_paragraph()
|
|
p.paragraph_format.space_after = PARA_AFTER
|
|
run = p.add_run(text)
|
|
run.font.size = BODY_SIZE
|
|
run.bold = bold
|
|
|
|
|
|
def _bullets(doc, items: list[str]) -> None:
|
|
for item in items:
|
|
p = doc.add_paragraph(style="List Bullet")
|
|
p.paragraph_format.left_indent = Inches(0.25)
|
|
p.paragraph_format.space_after = Pt(3)
|
|
p.clear()
|
|
run = p.add_run(item)
|
|
run.font.size = BODY_SIZE
|
|
|
|
|
|
def generate_cpni_procedure_statement(
|
|
# Identity
|
|
entity_name: str,
|
|
entity_abbr: str = "",
|
|
# Customer-facing contacts
|
|
support_email: str = "",
|
|
website: str = "",
|
|
# Signatory (typically an officer)
|
|
signatory_name: str = "",
|
|
signatory_title: str = "",
|
|
# Dates
|
|
effective_date: str = "",
|
|
next_review_date: str = "",
|
|
# Reviewer (defaults to Performance West Inc.)
|
|
reviewer_name: str = "Justin Hannah",
|
|
reviewer_company: str = "Performance West Inc.",
|
|
# Small wording knobs
|
|
is_wholesale: bool = False,
|
|
# Output
|
|
output_path: str = "/tmp/cpni_procedure_statement.docx",
|
|
) -> Optional[str]:
|
|
"""Generate the 10-section CPNI Procedure Statement as a DOCX file."""
|
|
if Document is None:
|
|
LOG.error("python-docx not installed")
|
|
return None
|
|
|
|
abbr = entity_abbr or entity_name
|
|
|
|
today = date.today()
|
|
effective = effective_date or today.strftime("%m/%d/%Y")
|
|
next_review = next_review_date or today.replace(year=today.year + 1).strftime("%m/%d/%Y")
|
|
|
|
doc = Document()
|
|
for section in doc.sections:
|
|
section.top_margin = Inches(1)
|
|
section.bottom_margin = Inches(1)
|
|
section.left_margin = Inches(1.25)
|
|
section.right_margin = Inches(1.25)
|
|
|
|
# Title
|
|
title_p = doc.add_paragraph()
|
|
title_p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
title_run = title_p.add_run(
|
|
"Customer Proprietary Network Information (CPNI) Procedure Statement"
|
|
)
|
|
title_run.font.size = Pt(14)
|
|
title_run.bold = True
|
|
title_run.font.color.rgb = NAVY
|
|
title_p.paragraph_format.space_after = Pt(2)
|
|
|
|
subtitle = doc.add_paragraph()
|
|
subtitle.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
sub_run = subtitle.add_run(entity_name)
|
|
sub_run.font.size = Pt(12)
|
|
sub_run.bold = True
|
|
subtitle.paragraph_format.space_after = Pt(18)
|
|
|
|
scope = (
|
|
"wholesale customer proprietary data"
|
|
if is_wholesale
|
|
else "Customer Proprietary Network Information (CPNI)"
|
|
)
|
|
|
|
# ── 1. Purpose ──────────────────────────────────────────────────
|
|
_heading(doc, "1. Purpose")
|
|
_body(doc, (
|
|
f"{entity_name} is committed to protecting the confidentiality and "
|
|
f"security of {scope} as required by the Federal Communications "
|
|
f"Commission (FCC) under Section 222 of the Communications Act. "
|
|
f"This document outlines the procedures {entity_name} follows to "
|
|
f"ensure compliance with CPNI regulations set forth in 47 CFR "
|
|
f"\u00a7\u00a7 64.2001 through 64.2011."
|
|
))
|
|
|
|
# ── 2. Definition of CPNI ──────────────────────────────────────
|
|
_heading(doc, "2. Definition of CPNI")
|
|
_body(doc, (
|
|
"CPNI includes information related to the quantity, technical "
|
|
"configuration, type, destination, location, and amount of use of "
|
|
"telecommunications services by customers. It does not include "
|
|
"subscriber list information such as name, address, and telephone "
|
|
"number."
|
|
))
|
|
|
|
# ── 3. Employee Training and Compliance ────────────────────────
|
|
_heading(doc, "3. Employee Training and Compliance")
|
|
_bullets(doc, [
|
|
f"{entity_name} trains all employees in the handling, protection, and authorized use of CPNI.",
|
|
"Employees are prohibited from accessing or disclosing CPNI unless required for legitimate business purposes.",
|
|
"Any violation of CPNI policies may result in disciplinary action, including termination.",
|
|
])
|
|
|
|
# ── 4. Customer Authentication and Access Control ──────────────
|
|
_heading(doc, "4. Customer Authentication and Access Control")
|
|
_bullets(doc, [
|
|
f"{entity_name} authenticates customers before disclosing CPNI via telephone, online, or in-store interactions.",
|
|
"Telephone access to CPNI requires authentication through a pre-established password or by sending information to the customer's registered address.",
|
|
"Online account access requires a secure login process with multi-factor authentication where applicable.",
|
|
"In-person requests require valid government-issued identification.",
|
|
])
|
|
|
|
# ── 5. Use of CPNI ─────────────────────────────────────────────
|
|
_heading(doc, "5. Use of CPNI")
|
|
_bullets(doc, [
|
|
f"{entity_name} does not use CPNI for marketing purposes unless the customer provides explicit opt-in consent.",
|
|
"CPNI may be used for billing, fraud prevention, and service-related notifications.",
|
|
"CPNI is not shared with third parties unless required by law or with customer authorization.",
|
|
])
|
|
|
|
# ── 6. Customer Rights and Notification ────────────────────────
|
|
_heading(doc, "6. Customer Rights and Notification")
|
|
_bullets(doc, [
|
|
"Customers have the right to restrict the use of their CPNI for marketing purposes.",
|
|
f"{entity_name} provides annual CPNI notices informing customers of their rights and how to manage their CPNI preferences.",
|
|
"Customers may change their CPNI settings by contacting customer service.",
|
|
])
|
|
|
|
# ── 7. CPNI Breach Notification and Reporting ──────────────────
|
|
_heading(doc, "7. CPNI Breach Notification and Reporting")
|
|
_bullets(doc, [
|
|
f"In the case of a CPNI breach, {entity_name} follows FCC guidelines for reporting incidents per 47 CFR \u00a7 64.2011.",
|
|
"Notification is made to the FCC, FBI, and U.S. Secret Service (the Federal Agencies) via the central reporting facility as soon as practicable, and no later than 30 days after reasonable determination of a breach.",
|
|
"Customers are notified of unauthorized access as soon as practicable and in no event later than 30 days after notification to law enforcement (unless a delay is requested by law enforcement).",
|
|
"The company maintains records of CPNI breaches and reports them to law enforcement as required.",
|
|
])
|
|
|
|
# ── 8. Record Keeping and Audits ───────────────────────────────
|
|
_heading(doc, "8. Record Keeping and Audits")
|
|
_bullets(doc, [
|
|
f"{entity_name} maintains records of customer CPNI approvals, marketing usage, and access logs for at least two years.",
|
|
"The company conducts annual audits to ensure compliance with CPNI policies and regulatory requirements.",
|
|
])
|
|
|
|
# ── 9. Enforcement and Penalties ───────────────────────────────
|
|
_heading(doc, "9. Enforcement and Penalties")
|
|
_bullets(doc, [
|
|
"Any employee found violating CPNI policies will be subject to disciplinary actions, including possible termination.",
|
|
f"{entity_name} complies with all regulatory enforcement actions and may be subject to fines for non-compliance. Per FCC Enforcement Advisory DA-26-139, failure to comply with the CPNI rules may subject the company to monetary forfeitures of up to $251,322 per violation (up to a maximum of $2,513,215 for continuing violations).",
|
|
])
|
|
|
|
# ── 10. Contact Information ────────────────────────────────────
|
|
_heading(doc, "10. Contact Information")
|
|
_body(doc, (
|
|
f"For questions or concerns regarding CPNI policies, customers may "
|
|
f"contact {entity_name} Support:"
|
|
))
|
|
if support_email:
|
|
_body(doc, f"Email: {support_email}")
|
|
if website:
|
|
_body(doc, f"Website: {website}")
|
|
|
|
# ── Footer: dates + signatory ──────────────────────────────────
|
|
doc.add_paragraph("")
|
|
_body(doc, f"Effective Date: {effective}")
|
|
if signatory_name:
|
|
title_suffix = f", {signatory_title}" if signatory_title else ""
|
|
_body(doc, f"Signatory: {signatory_name}{title_suffix}, {entity_name}")
|
|
if reviewer_name:
|
|
_body(doc, f"Reviewed By: {reviewer_name}, {reviewer_company}")
|
|
_body(doc, f"Next Review Date: {next_review}")
|
|
|
|
out = Path(output_path)
|
|
out.parent.mkdir(parents=True, exist_ok=True)
|
|
doc.save(str(out))
|
|
LOG.info("CPNI Procedure Statement generated: %s", out)
|
|
return str(out)
|