# Harden a BYOC Deployment

This page applies to EMQX Cloud BYOC deployments on AWS, Google Cloud, and Azure. After the deployment is **Running** and the EMQX Dashboard and MQTT clients are reachable, restrict access and retire temporary provisioning credentials. Check the actual connection information, load balancer listeners, and health checks before changing cloud rules.

## Secure the EMQX Dashboard

1. Sign in at `https://<deployment-domain>:18084` and change the initial administrator password.
2. Enable [TOTP multi-factor authentication](https://docs.emqx.com/en/emqx/latest/multi-factor-authn/multi-factor-authentication.html) for administrators. Give each administrator an individual account with the required role, and store emergency credentials in an approved password manager.
3. Configure MQTT client authentication and authorization for each application. Limit topic access and integration credentials to what the application needs.

## Restrict Network Access

Separate management traffic from client traffic. Allow Dashboard access only from approved public IP ranges, a corporate VPN, or a controlled bastion network. Review the actual listener and firewall configuration for your deployment before changing these default ports:

| TCP port | Purpose | Recommendation |
| --- | --- | --- |
| `18084` | EMQX Dashboard | Allow only approved management sources. |
| `1883`, `8083` | Plaintext MQTT and WebSocket | Close public access unless explicitly required. |
| `8883`, `8084` | MQTT over TLS and WebSocket over TLS | Keep only the protocols clients use; restrict sources where practical. |
| `8443` | REST API and required deployment management access | Preserve the access and port mapping required by this deployment. |

Do not close or remap `8443` outside the deployment's documented requirements. Preserve Agent and cluster communication, and do not expose internal or health-check ports broadly.

### AWS

Review the Network Load Balancer listeners, target groups, and [security group rules](https://docs.aws.amazon.com/vpc/latest/userguide/security-group-rules.html) on the load balancer, if attached, and broker instances. Security group allow rules are combined: adding a narrow rule does not override an existing broad one. Remove broad rules and verify effective access at both the load balancer and targets. Preserve the target and health-check ports configured in each target group; confirm that targets remain healthy.

### Google Cloud

Review VPC firewall rules and load balancer forwarding rules together. Remove existing broad Internet allow rules for Dashboard and unused client ports; adding a narrower allow rule alone does not restrict traffic already permitted. Preserve access on the health-check and internal communication ports configured for the deployment. Follow the [firewall requirements for the actual load balancer type](https://cloud.google.com/load-balancing/docs/firewall-rules), including its health-check source ranges, and confirm that backends remain healthy.

### Azure

Use separate Network Security Group (NSG) rules for management and application traffic. Review [effective rules](https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview) on the subnet and network interfaces, including rule priorities; remove broad Internet allow rules that still grant access. Preserve the [Azure Load Balancer health probes](https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-custom-probe-overview) and confirm that the backend pool remains healthy.

## Retire Temporary Provisioning Credentials

First confirm that the provisioning identity and its credentials are not used by running instances, integrations, or automation. Preserve runtime identities and shared credentials. For later start, stop, or delete operations, use the [current guide and commands](./stop_delete_deployment.md#byoc) for that deployment and retire temporary credentials afterward.

### AWS

Deactivate the creation-only IAM access key, verify Dashboard, MQTT, and EMQX Cloud monitoring, then delete the key in IAM and remove local copies. Remove the IAM user and policy only after confirming that they have no other use or bindings. Do not use root-user access keys.

### Google Cloud

[Disable the creation-only service account JSON key](https://cloud.google.com/iam/docs/keys-disable-enable), verify the deployment, then delete the key in Google Cloud IAM and remove local copies. Deleting only the JSON file does not revoke the key. Delete the service account or its IAM bindings only after confirming that VMs, integrations, and automation do not depend on them. Scope credentials for future operations to the BYOC project.

### Azure

If the Microsoft Entra application and service principal were created only for BYOC provisioning, retire their secret and resource-group role assignment after deployment verification and a dependency check. Delete the application and service principal only when your agreed operating model confirms that future lifecycle operations can use newly provisioned credentials. For those operations, follow the guide to create a new service principal with the `Contributor` role scoped to the BYOC resource group; do not grant subscription-wide permissions.

## Remove the Temporary Bootstrap Environment

If you used a temporary Ubuntu VM to run deployment creation, identify it by its own name or tags before removing it. Verify the deployment and securely save required recovery material first. Remove only that VM and resources confirmed to belong exclusively to it; do not select resources for deletion by type alone. If ownership or dependencies are unclear, retain the resource until verified. Remove local copies of cloud credentials, TLS private keys, deployment packages, Terraform state, and logs or shell history containing credentials from the bootstrap environment after securing required recovery material.

Preserve all resources created for the BYOC deployment, including broker nodes, the `emqxbyoc-...-agent-...` VM, key pairs, disks, snapshots, network interfaces, images, networks, load balancers, IP addresses, and DNS records. Preserve shared resources as well.

## Maintain Certificates and Audit Records

Assign a certificate renewal owner and set expiry alerts. Use the supported [certificate update](./byoc_ssl.md#update-certificate) procedure with a certificate matching the deployment hostname, its private key, and the required chain. Verify MQTT TLS connections after renewal.

- **AWS:** Maintain a [CloudTrail trail](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/best-practices-security.html) for ongoing management-event records, and enable [GuardDuty](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_settingup.html) according to your account security baseline.
- **Google Cloud:** Review [Cloud Audit Logs](https://cloud.google.com/logging/docs/audit/best-practices) and set retention for your security requirements.
- **Azure:** Review the [Activity Log](https://learn.microsoft.com/en-us/azure/azure-monitor/platform/activity-log) and export it if you need retention beyond its default period.

Review cloud identity, network, and deployment resource changes according to your security policy.

## Verify the Hardened Deployment

- The deployment is **Running**, and broker nodes and load balancer backends are healthy.
- The Dashboard is reachable only from approved sources; administrator passwords are changed and MFA is enabled.
- Only required MQTT client ports are reachable, and authentication and authorization work.
- Port `8443`, Agent communication, and health checks still work.
- Temporary credentials and bootstrap artifacts are removed without affecting runtime identities.
- Certificate renewal, expiry alerts, and audit records are in place.

After changing network rules, test Dashboard access from both allowed and disallowed sources, then recheck MQTT clients and EMQX Cloud monitoring.
