Config/DomainConfig.example.psd1

<#
    DmarcDeploymentKit - example domain register.

    This is a FICTIONAL register (contoso.* domains) used by the module's own
    tests and as a template for your own configuration. It ships inside the
    module so the module itself never has to know a real organization's
    domains, DNS zone identifiers or observed DMARC pass rates - none of
    which belong in a shared, generic module.

    To use DmarcDeploymentKit against your own tenant: copy this file, edit
    the Domains array to match your own domain register and DNS provider,
    then point the module at it with either

        Set-DmarcConfigPath -Path ./Config/YourOrgDomainConfig.psd1

    or the DMARCDEPLOYMENTKIT_CONFIG_PATH environment variable set before the
    module is imported. Every value below is either observed operational
    state or a target you define; the module hard-codes none of it.
#>

@{
    Metadata       = @{
        Organisation     = 'Contoso'
        ConfigVersion    = '1.0.0'
        ReportingAddress = 'mailto:dmarc@contoso.com'

        # DnsProvider selects the implementation Set-DmarcPolicy uses to
        # publish a change artefact: 'Route53' writes an AWS Route 53
        # change-batch JSON and, with DnsWriteAccess and -Apply, invokes the
        # AWS CLI; 'Manual' writes a plain-text instruction file for any DNS
        # host with no automatable API and never applies anything itself.
        DnsProvider      = 'Route53'
        DnsWriteAccess   = $false   # write access not yet approved; DNS publication is manual
        DefaultTtl       = 300      # short TTL during enforcement ramp so rollback is fast
        SteadyStateTtl   = 3600
    }

    # ------------------------------------------------------------------
    # Phase definitions. Each phase yields a DMARC policy and percentage.
    # ------------------------------------------------------------------
    Phases         = @{
        None             = @{
            Order = 0; Policy = 'none'; Percent = 100; SubPolicy = 'none'
            Description = 'Baseline monitoring. No enforcement.'
            SoakDays    = 30
        }
        QuarantinePilot  = @{
            Order = 1; Policy = 'quarantine'; Percent = 5; SubPolicy = 'none'
            Description = 'First enforcement step. 5 per cent of failing mail quarantined.'
            SoakDays    = 7
        }
        QuarantineRamp25 = @{
            Order = 2; Policy = 'quarantine'; Percent = 25; SubPolicy = 'none'
            Description = 'Ramp step 2.'
            SoakDays    = 7
        }
        QuarantineRamp50 = @{
            Order = 3; Policy = 'quarantine'; Percent = 50; SubPolicy = 'quarantine'
            Description = 'Ramp step 3. Sub-domain policy engaged.'
            SoakDays    = 14
        }
        QuarantineFull   = @{
            Order = 4; Policy = 'quarantine'; Percent = 100; SubPolicy = 'quarantine'
            Description = 'Committed target state.'
            SoakDays    = 30
        }
        Reject           = @{
            Order = 5; Policy = 'reject'; Percent = 100; SubPolicy = 'reject'
            Description = 'Requires separate business approval before use.'
            SoakDays    = 30
        }
    }

    # Common DMARC tags applied to all active-sending domains.
    DmarcDefaults  = @{
        Rua            = 'mailto:dmarc@contoso.com'
        Ruf            = 'mailto:dmarc@contoso.com'
        FailureOption  = '1'
        DkimAlignment  = 'r'      # relaxed; sub-domain senders in use
        SpfAlignment   = 'r'
        ReportInterval = 86400
    }

    # Stricter defaults for non-sending domains, where no legitimate mail exists.
    ParkedDefaults = @{
        Rua            = 'mailto:dmarc@contoso.com'
        Ruf            = ''
        FailureOption  = '1'
        DkimAlignment  = 's'
        SpfAlignment   = 's'
        ReportInterval = 86400
    }

    # ------------------------------------------------------------------
    # Domain register.
    # Classification : ActiveSending | SubDomain | Parked | MicrosoftOwnedZone
    # TargetPhase : the phase this domain is authorised to reach
    # Enforceable : $false blocks Set-DmarcPolicy beyond phase None
    # HostedZoneId : Route 53 hosted-zone ID; ignored by the Manual provider
    # ------------------------------------------------------------------
    Domains        = @(
        @{
            Name           = 'contoso.com'
            Classification = 'ActiveSending'
            HostedZoneId   = 'Z0000000EXAMPLE1'
            TargetPhase    = 'QuarantineFull'
            Enforceable    = $true
            M365Dkim       = $true
            CurrentState   = @{
                Spf              = 'v=spf1 include:spf.protection.outlook.com -all'
                SpfLookups       = 1
                Dmarc            = 'v=DMARC1; p=none; rua=mailto:dmarc@contoso.com'
                DkimEnabled      = $true
                DkimStatus       = 'Valid'
                ObservedVolume   = 38000
                ObservedPassRate = 98.4
            }
            TargetSpf      = 'v=spf1 include:spf.protection.outlook.com -all'
            Notes          = 'Highest-volume domain. Meets the pass-rate threshold; authorised to the committed target phase.'
        }
        @{
            Name           = 'partner.contoso.com'
            Classification = 'ActiveSending'
            HostedZoneId   = 'Z0000000EXAMPLE1'
            TargetPhase    = 'QuarantineFull'
            Enforceable    = $false   # BLOCKED - a third-party sender is unaligned; see Notes
            M365Dkim       = $true
            CurrentState   = @{
                Spf              = 'v=spf1 include:spf.protection.outlook.com include:_spf.example-esp.com -all'
                SpfLookups       = 2
                Dmarc            = 'v=DMARC1; p=none; rua=mailto:dmarc@contoso.com'
                DkimEnabled      = $false
                DkimStatus       = 'CnameMissing'
                ObservedVolume   = 14000
                ObservedPassRate = 0.2
            }
            TargetSpf      = 'v=spf1 include:spf.protection.outlook.com include:_spf.example-esp.com -all'
            Notes          = 'Critical path: a third-party email service provider is signing unaligned. Enforcement is blocked until that remediation completes.'
        }
        @{
            Name           = 'noreply.contoso.com'
            Classification = 'SubDomain'
            HostedZoneId   = 'Z0000000EXAMPLE1'
            TargetPhase    = 'QuarantineFull'
            Enforceable    = $true
            M365Dkim       = $false
            CurrentState   = @{
                Spf              = 'v=spf1 include:spf.protection.outlook.com -all'
                SpfLookups       = 1
                Dmarc            = ''
                DkimEnabled      = $null
                DkimStatus       = 'NotApplicable'
                ObservedVolume   = 0
                ObservedPassRate = $null
            }
            TargetSpf      = 'v=spf1 include:spf.protection.outlook.com -all'
            Notes          = 'Sub-domain of contoso.com. Inherits the organisational policy via sp= unless an explicit record is published.'
        }
        @{
            Name           = 'contoso-labs.io'
            Classification = 'ActiveSending'
            HostedZoneId   = 'Z0000000EXAMPLE2'
            TargetPhase    = 'None'   # unenforced - telemetry-blind
            Enforceable    = $false
            M365Dkim       = $true
            CurrentState   = @{
                Spf              = 'v=spf1 include:spf.protection.outlook.com -all'
                SpfLookups       = 1
                Dmarc            = 'v=DMARC1; p=none; rua=mailto:dmarc@contoso.com'
                DkimEnabled      = $true
                DkimStatus       = 'Valid'
                ObservedVolume   = 0
                ObservedPassRate = $null
            }
            TargetSpf      = 'v=spf1 include:spf.protection.outlook.com -all'
            Notes          = 'Publishes rua but produced no aggregate reports in the observation window. Remains at p=none pending telemetry.'
        }
        @{
            Name           = 'holdings.contoso.net'
            Classification = 'Parked'
            HostedZoneId   = 'Z0000000EXAMPLE3'
            TargetPhase    = 'QuarantineFull'
            Enforceable    = $true
            M365Dkim       = $false
            CurrentState   = @{
                Spf = ''; SpfLookups = $null; Dmarc = ''
                DkimEnabled = $null; DkimStatus = 'NotApplicable'
                ObservedVolume = 0; ObservedPassRate = $null
            }
            TargetSpf      = 'v=spf1 -all'
            Notes          = 'No SPF, no DMARC, not an accepted domain. Null MX proposed.'
        }
        @{
            Name           = 'contoso.onmicrosoft.com'
            Classification = 'MicrosoftOwnedZone'
            HostedZoneId   = ''
            TargetPhase    = 'None'
            Enforceable    = $false
            M365Dkim       = $true
            CurrentState   = @{
                Spf              = 'v=spf1 include:spf.protection.outlook.com -all'
                SpfLookups       = 1
                Dmarc            = ''
                DkimEnabled      = $true
                DkimStatus       = 'Valid'
                ObservedVolume   = 0
                ObservedPassRate = $null
            }
            TargetSpf      = ''
            Notes          = 'Microsoft owns this zone. No SPF or DMARC treatment is possible here. Excluded from all DNS actions.'
        }
    )

    # Go/no-go thresholds applied by Invoke-DmarcPhaseValidation.
    Thresholds     = @{
        MinimumDmarcPassRate = 98.0  # per cent, required before any pct increase
        MaximumSpfLookups    = 10
    }
}