A JBoss EAP or WildFly server whose management interface is reachable from the network is one stolen password away from arbitrary code deployment, because any authenticated administrator can push a deployment that runs with the server's privileges. Modern servers carry that risk whenever the management port, the users file or the default permission model is left as installed. This guide covers WildFly and Red Hat JBoss EAP (Red Hat's supported product built from WildFly) together: how management and application identity work through the Elytron subsystem, how to switch from the default "simple" access model to role-based access control, how to protect the credentials the server holds, what to audit, and a hardening baseline. It is for middleware administrators, platform engineers and security teams responsible for Java application servers.
This is an independent guide from NHI Mgmt Group, based on the WildFly project's public documentation as of November 2026. It is not sponsored or reviewed by Red Hat or the WildFly project. Product features change, so confirm settings against the WildFly project's current documentation.
Key takeaways
- Keep management on localhost or a management network. The management interface binds to
jboss.bind.address.management, 127.0.0.1 by default, on port 9990 (HTTP) or 9993 (HTTPS); never start a server with-bmanagement=0.0.0.0on a routable network. - The default access model is all or nothing. The "simple" provider gives every authenticated administrator all permissions; switch to the "rbac" provider and use the seven standard roles.
- Treat mgmt-users.properties as a secret. It holds hashes of username, realm and password that WildFly's own docs warn can be reused on any server with the same realm.
- Move passwords into an Elytron credential store. Datasource, keystore and LDAP passwords belong in a credential store or behind encrypted expressions, not in
standalone.xml. - Management audit logging is off by default. Enable it, add Elytron security event auditing, and send both to syslog over TLS.
How identity and access work in JBoss EAP and WildFly
Modern WildFly (the documentation index lists WildFly 42 as current) and JBoss EAP 8 use the Elytron subsystem for both management and application security. Elytron separates where identities live (security realms), how a request is authenticated (HTTP and SASL authentication factories with mechanisms such as DIGEST, BASIC, FORM, CLIENT_CERT and BEARER_TOKEN) and how identities become roles (security domains with role decoders and mappers).
| Surface | Default | Identity source | Security note |
|---|---|---|---|
HTTP management interface (web console, /management API) | Port 9990 on the management interface, 127.0.0.1; authentication factory management-http-authentication using HTTP Digest | ManagementRealm properties realm, mgmt-users.properties | No default user ships, so nobody can log in until add-user.sh creates one |
| Native management via HTTP upgrade (jboss-cli) | Same port, management-sasl-authentication | ManagementRealm, plus silent local authentication | JBOSS-LOCAL-USER lets a local OS user with file access authenticate as $local |
| HTTPS management | Socket binding management-https on 9993, not enabled until configured | As above, optionally client certificates | Enable with the CLI command security enable-ssl-management |
| Applications | Public interface, 127.0.0.1 by default, port 8080/8443 | ApplicationRealm (application-users.properties), LDAP, database, OIDC or token realms | Mapped through Elytron security domains; see the Jakarta EE Security |
- Prefer central identity for administrators: properties files are fine for a single lab server but give no MFA, lockout or leaver process. For production, back the management security domain with LDAP or an identity provider so administrator accounts are disabled centrally. See the LDAP Security Deep Dive Guide.
- Understand silent local authentication: by default a CLI user on the same host is authenticated as
$local, and the default RBAC mapping gives$localthe SuperUser role. Anyone with a shell as the server's OS user on that host is therefore effectively SuperUser. Remove theJBOSS-LOCAL-USERmechanism from the SASL factory where host access is shared, or keep it and treat OS access to the server account as privileged. - Bind addresses decide exposure: both the management and public interfaces default to 127.0.0.1. Production startup scripts commonly pass
-bfor the public interface; review every script and systemd unit for-bmanagementorjboss.bind.address.management.
Admin roles and privileged access
WildFly ships two access control providers. The "simple" provider is the default and, as the WildFly Admin Guide puts it, any authenticated administrator has all permissions. The "rbac" provider adds seven standard roles. Enable it with /core-service=management/access=authorization:write-attribute(name=provider,value=rbac) after mapping at least one user to SuperUser.
| Role | Permissions (WildFly Admin Guide) | Typical holder |
|---|---|---|
| Monitor | Read-only; cannot modify any resource | Monitoring tools, service desk |
| Operator | Monitor plus runtime changes (for example restart a server), no persistent configuration changes | On-call operations |
| Maintainer | Operator plus persistent configuration changes; no security-sensitive resources | Middleware engineers |
| Deployer | Like Maintainer, but persistent changes limited to application resources such as deployments | CI/CD deployment identity |
| Administrator | All permissions except reading or writing the administrative audit logging resources | Platform owners |
| Auditor | Can read anything; can modify only audit logging resources | Security or compliance team |
| SuperUser | All permissions, equivalent to the old JBoss AS 7 administrator | Break-glass only |
- Separate Administrator from Auditor: the two roles exist so that those who perform administrative actions cannot switch off the record of them. Give audit configuration to the Auditor role only.
- Give pipelines Deployer, not SuperUser: a CI/CD identity that only deploys applications should not be able to change security realms or datasources.
- Remember deployment equals code execution: Maintainer, Deployer, Administrator and SuperUser can all deploy code that runs inside the JVM with the server's OS privileges. Treat these roles as privileged access and route them through your PAM process. See the Privileged Access Management Guide.
- Protect the filesystem too: anyone who can write to
standalone/configurationor, where the deployment scanner is enabled, thedeploymentsdirectory, can bypass RBAC entirely. Run the server as a dedicated non-root user and restrict those directories. - Disable the console where unused: if all administration is through the CLI or automation, turn off the web console on the HTTP interface to reduce the attack surface.
Integrations, API tokens and service accounts
An application server is a heavy holder of non-human credentials: database passwords in datasources, keystore passwords for TLS, LDAP bind passwords, messaging credentials and outbound HTTP client secrets. In older configurations these sit in plain text in standalone.xml or domain.xml.
| Option | How it works | When to use |
|---|---|---|
| Plain text in configuration | Password attribute in the XML | Never in production |
| KeyStoreCredentialStore | Elytron credential store backed by a Java KeyStore (JCEKS by default with elytron-tool.sh); resources reference credentials by alias | Default choice for on-premises servers |
| Encrypted expressions | ${ENC::Resolver:...} values decrypted at runtime with a secret key from a credential store | When attributes must stay in configuration files under version control |
| PropertiesCredentialStore | Stores secret keys in a properties file with no protection | Only to bootstrap an initial key, as the WildFly docs describe |
| External vault | Credential store backed by HashiCorp Vault (documented integration) | Fleets that already run a central secrets platform |
- Migrate off the legacy Vault: the credential store replaces the old picketbox Vault used by earlier releases; plan the move as part of any EAP 7 to 8 migration.
- Protect the store's own secret: a credential store is only as strong as the password or key that opens it. Keep that bootstrap secret outside the server's configuration directory with tight file permissions, or inject it at start-up. See the Secret Zero Bootstrap Guide.
- Use dedicated, least-privilege accounts: each datasource gets its own database account with only the rights the application needs; the LDAP bind account is read-only and scoped to the search bases used.
- Automation identities: give deployment tools their own management user mapped to Deployer, and rotate its password or certificate on a schedule. Do not share a human administrator's credentials with a pipeline. See the Java Keystores Guide for the TLS side.
Logging and detection
WildFly has two complementary audit sources. Management audit logging records operations on the management model as JSON; it is built in but disabled by default, writing to audit-log.log under jboss.server.data.dir once enabled, with log-boot and log-read-only options and a syslog handler. Elytron audit uses security event listeners to record successful and failed authentication, to a file in SIMPLE or JSON format or to syslog over UDP, TCP or TCP with TLS in RFC 5424 format.
| Signal | Source | Related technique |
|---|---|---|
| Deployments added or replaced outside a change window | Management audit log, server log | T1505.003 Web Shell |
| New management users, role mapping changes, provider switched back to simple | Management audit log; file integrity monitoring on mgmt-users.properties | T1136 Create Account, T1098 Account Manipulation |
| Audit logger disabled or handler removed | Management audit log, syslog gap | T1685 Disable or Modify Tools |
| Repeated failed management logins | Elytron audit | T1110 Brute Force |
Requests to /management, /console or legacy paths such as /jmx-console and /invoker from untrusted networks | Firewall, reverse proxy, access logs | T1190 Exploit Public-Facing Application |
| Java process spawning shells or writing new JSP or WAR files | EDR, auditd | T1059 Command and Scripting Interpreter |
Metrics that show it is working
- Exposure: servers with management ports 9990 or 9993 reachable from outside the management network (target: zero).
- Access model: share of servers running the rbac provider, and number of users mapped to SuperUser.
- Secrets: plain-text password attributes found in configuration files by scanning (target: zero).
- Audit coverage: servers with management and Elytron audit forwarding to syslog, and hours since the last event received.
- Patch level: servers on a supported WildFly or EAP release and days behind the latest security update.
Hardening baseline
| Area | Control | Configuration detail |
|---|---|---|
| Management exposure | Keep management on 127.0.0.1 or a dedicated management VLAN; firewall 9990 and 9993 | jboss.bind.address.management; review start-up flags |
| Management transport | HTTPS only for remote management | security enable-ssl-management; ssl-context and secure-socket-binding=management-https on http-interface |
| Access control | rbac provider, named users mapped to roles, SuperUser for break-glass | access=authorization provider and role-mapping |
| Local authentication | Remove JBOSS-LOCAL-USER where the host is shared | Edit mechanism-configurations on the SASL authentication factory |
| Users file | Owner-only permissions on mgmt-users.properties and mgmt-groups.properties; unique realm per environment | Hashes include the realm name, so shared realm names let a hash work on other servers |
| Credentials | Credential store or encrypted expressions for every password | elytron-tool.sh credential-store, credential-reference attributes |
| Audit | Enable management audit logging and Elytron audit; forward to syslog over TLS | /core-service=management/access=audit; Elytron syslog audit log with an SSL context |
| Unused subsystems | Provision only the features you need | Galleon layers or a trimmed configuration; remove unused connectors and the deployment scanner in production |
| OS | Dedicated non-root service account, restricted configuration and deployment directories | See the Linux Server Hardening Guide |
| Patching and support | Track Red Hat errata or WildFly releases; retire legacy JBoss AS | See below |
Phased rollout
- Discover: find every JBoss and WildFly instance, its version, its bind addresses and whether 9990, 9993, 8080 or legacy JBoss paths answer from user networks.
- Contain exposure: firewall management ports and remove
-bmanagementoverrides before any other change. - Check for compromise: review deployments, management users and recent configuration history against your change records.
- Turn on audit: enable both audit sources so the rest of the rollout is recorded.
- Introduce RBAC: map named users and groups to roles in the role-mapping first, test with each role, then switch the provider to rbac.
- Move secrets: create credential stores and replace plain-text passwords alias by alias.
- Trim and patch: remove unused subsystems, enable HTTPS management and bring servers to a supported release.
Testing and rollback: make each change on a staging server and keep a copy of standalone.xml or domain.xml; WildFly also keeps configuration history in the standalone_xml_history directory. Keep a local SuperUser mapping until RBAC has been tested, so a mapping error can be reversed from the CLI. Test every datasource after moving its password to a credential store, because a wrong alias stops the application at start-up.
Legacy releases and support
Old JBoss AS and EAP generations still run in some estates, often behind internal applications nobody owns. Apply Red Hat's security updates promptly and keep every server on a supported release. Red Hat places EAP on its long-life cycle (four years of full support and three of maintenance) and its policy page records that EAP 7 maintenance support was extended to 30 June 2025, with extended life support phases since then; check the Red Hat life cycle pages for current dates (NIST SP 800-53 SA-22 Unsupported System Components). Small estates should migrate to a supported release; large ones should isolate anything that cannot move. Deserialisation is the common thread in many Java server flaws; see the Insecure Deserialisation Guide.
Common misconfigurations
- Management bound to all interfaces:
-bmanagement=0.0.0.0copied from a tutorial exposes the console and API to every network the host is on. - The simple provider in production: every administrator, including the deployment pipeline and the monitoring account, can change security realms and disable auditing.
- Same realm name and admin password everywhere: one copied
mgmt-users.propertiesunlocks every server in the fleet. - Plain-text datasource passwords: configuration backups and Git repositories become a source of production database credentials.
- Audit left at its default: with management audit logging disabled, a malicious deployment leaves only the server log as evidence, on a host the attacker controls.
- Forgotten legacy JBoss: an old JBoss AS with
/jmx-consoleor/invokerreachable from user networks.
Framework mapping
| Control area | NIST SP 800-53 Rev. 5 | NIST CSF 2.0 | CIS Controls v8.1 | ISO/IEC 27001:2022 Annex A |
|---|---|---|---|---|
| Management exposure and HTTPS | SC-7, SC-8, AC-17 | PR.IR-01 | 4, 12 | A.8.20, A.8.22 |
| RBAC and role separation | AC-2, AC-6 | PR.AA-05 | 5, 6 | A.5.15, A.8.2 |
| Credentials and credential stores | IA-5 | PR.AA-01 | 3 | A.5.17 |
| Audit logging | AU-2, AU-9, AC-6(9) | PR.PS-04 | 8 | A.8.15 |
| Configuration baseline | CM-6, CM-7 | PR.PS-01 | 4 | A.8.9 |
| Patching and legacy releases | SI-2, SA-22 | ID.RA-01 | 7 | A.8.8 |
Practitioner checklist
- Confirm management interfaces bind to 127.0.0.1 or a management network and firewall ports 9990 and 9993.
- Enable HTTPS for any remote management with
security enable-ssl-management. - Map named users to RBAC roles, then switch the provider from simple to rbac.
- Give pipelines the Deployer role and keep SuperUser for break-glass.
- Decide whether to keep silent local authentication and treat OS access to the server account as privileged.
- Restrict permissions on users files and use unique realm names per environment.
- Move every password into an Elytron credential store or encrypted expression.
- Enable management and Elytron audit logging and forward both to syslog over TLS.
- Remove unused subsystems and the production deployment scanner.
- Find and retire or isolate legacy JBoss AS and unsupported EAP releases.
Standards and references
- WildFly: Documentation
- WildFly: Admin Guide, Role Based Access Control
- WildFly: Admin Guide, Audit logging
- WildFly: Elytron Security, Credential Store
- WildFly: Using the Elytron Subsystem
- Red Hat: JBoss Middleware Life Cycle and Update Policies
- Red Hat: Security Updates
- NIST: SP 800-53 Rev. 5
Related NHI Mgmt Group resources: Jakarta EE Security · Apache Tomcat Hardening Guide · Java and Spring Security Guide · Secret Zero Bootstrap Guide · Privileged Access Management Guide