Updated October 2026: I re-tested ASA RADIUS AAA against FreeRADIUS on ASAv 9.24(1), including wrong-NAS and wrong-secret faults that both time out (so a hang is not proof the secret is correct). Details are in the new section before Key Takeaways.
Authentication, Authorization, and Accounting (AAA) on a Cisco ASA decides three things for every VPN session: who is the user, what are they allowed to do, and what activity should be logged. The three protocols you can wire into the ASA for these jobs are LDAP (commonly Microsoft Active Directory), RADIUS, and TACACS+. Each one has its sweet spot, and a real production ASA frequently uses all three at the same time, just for different functions. This article walks the configuration of all three on Cisco ASA 9.x and shows when to use which. In October 2026 I re-tested the RADIUS part on ASAv 9.24(1) built in my home lab; LDAP, TACACS+, LOCAL fallback and accounting were not re-tested (see the PingLabz ASA reference notes and the re-test section).
Before configuring AAA, you should already have a working AnyConnect connection profile (see Cisco ASA AnyConnect SSL VPN Configuration) using local users. The AAA server group then plugs into the existing tunnel-group's authentication-server-group attribute, replacing or augmenting the local fallback.
When to Use Which Protocol
ldap attribute-map.The common production split: LDAP for VPN authentication and group lookup, RADIUS for VPN authentication when MFA is required, TACACS+ for admin access into the ASA itself.
AAA Server Groups
All AAA on the ASA is configured in two layers: an aaa-server group (the protocol and the list of servers) and the references to that group from features that consume AAA (tunnel-groups, aaa authentication ssh console, etc.).
From the original build of this lab, three server groups are configured (one per protocol). Only the RADIUS group was re-tested in October 2026, and the secrets show as masked:
ASA-PERIM# show running-config aaa-server
aaa-server RADIUS-VPN protocol radius
aaa-server RADIUS-VPN (inside) host 10.10.0.10
retry-interval 2
timeout 5
key *****
authentication-port 1812
accounting-port 1813
aaa-server LDAP-VPN protocol ldap
aaa-server LDAP-VPN (inside) host 10.10.0.20
server-port 636
ldap-base-dn dc=pinglabz,dc=lab
ldap-scope subtree
ldap-naming-attribute sAMAccountName
ldap-login-password *****
ldap-login-dn cn=svc-asa,ou=Service,dc=pinglabz,dc=lab
ldap-over-ssl enable
server-type microsoft
aaa-server TACACS-ADMIN protocol tacacs+
aaa-server TACACS-ADMIN (inside) host 10.10.0.30
timeout 5
key *****
Each server group has a name (RADIUS-VPN, LDAP-VPN, TACACS-ADMIN), a protocol, and one or more host entries. The ASA tries hosts in order; if the first is unreachable after the configured retry/timeout, it tries the second.
Configure RADIUS for VPN Authentication
Two-step pattern: declare the group with its protocol, then add hosts with their shared secret and timing.
ASA-PERIM(config)# aaa-server RADIUS-VPN protocol radius
ASA-PERIM(config)# aaa-server RADIUS-VPN (inside) host 10.10.0.10
ASA-PERIM(config-aaa-server-host)# key <RADIUS_KEY>
ASA-PERIM(config-aaa-server-host)# authentication-port 1812
ASA-PERIM(config-aaa-server-host)# accounting-port 1813
ASA-PERIM(config-aaa-server-host)# timeout 5
ASA-PERIM(config-aaa-server-host)# retry-interval 2
ASA-PERIM(config-aaa-server-host)# exit
Then bind the group into a tunnel-group:
ASA-PERIM(config)# tunnel-group SSL_PROFILE general-attributes
ASA-PERIM(config-tunnel-general)# authentication-server-group RADIUS-VPN LOCAL
ASA-PERIM(config-tunnel-general)# accounting-server-group RADIUS-VPN
The LOCAL after RADIUS-VPN means: try RADIUS first, and fall back to the local username database if all RADIUS hosts are unreachable. Including LOCAL fallback for VPN authentication means a RADIUS outage does not cut off all remote access at exactly the worst moment (when admins need to log in to fix it). I did not re-test the LOCAL fallback in my lab.
Then test it directly. This is from my home lab on ASAv 9.24(1), with the test password replaced by a placeholder. Note the 5-second timeout, which is what this server was configured with:
ASA-AAA58# test aaa-server authentication RADIUS-VPN host 10.58.0.10 username vpnuser password <TEST_PASSWORD>
INFO: Attempting Authentication test to IP address (10.58.0.10) (timeout: 5 seconds)
INFO: Authentication Successfultest aaa-server is the fastest check, but a timeout does not prove the shared secret is correct, or that the server is unreachable. On ASAv 9.24(1) with FreeRADIUS, both a wrong NAS IP in clients.conf and a wrong ASA key produced ERROR: Authentication Server not responding: No active server found after the 5-second timeout, while ping still succeeded and, for the secret fault, the server still received the requests. An immediate ERROR: Authentication Rejected: AAA failure is the wrong-password path. Confirm with the RADIUS server log or a capture, not the timeout alone.
Configure LDAP (Active Directory) for Authorization
LDAP setup needs more attributes than RADIUS because there is no standard "give me the user's password and let me see if it matches" call. The ASA binds to the directory as a service account, then performs a sub-tree search to find the user by their login attribute, then re-binds as the user with their typed password.
ASA-PERIM(config)# aaa-server LDAP-VPN protocol ldap
ASA-PERIM(config)# aaa-server LDAP-VPN (inside) host 10.10.0.20
ASA-PERIM(config-aaa-server-host)# ldap-base-dn dc=pinglabz,dc=lab
ASA-PERIM(config-aaa-server-host)# ldap-scope subtree
ASA-PERIM(config-aaa-server-host)# ldap-naming-attribute sAMAccountName
ASA-PERIM(config-aaa-server-host)# ldap-login-dn cn=svc-asa,ou=Service,dc=pinglabz,dc=lab
ASA-PERIM(config-aaa-server-host)# ldap-login-password <LDAP_BIND_PASSWORD>
ASA-PERIM(config-aaa-server-host)# server-type microsoft
ASA-PERIM(config-aaa-server-host)# ldap-over-ssl enable
ASA-PERIM(config-aaa-server-host)# server-port 636
ASA-PERIM(config-aaa-server-host)# exit
The eight attributes:
ldap-base-dn: the root of the LDAP tree to search from. Typically your AD domain DN.ldap-scope subtree: search the entire sub-tree below the base DN. The other choice (onelevel) only searches one level deep, which is rarely what you want.ldap-naming-attribute sAMAccountName: the attribute that identifies a user.sAMAccountNameis the AD short name (e.g.vpnuser). For OpenLDAP, it would beuid; for AD via UPN, useuserPrincipalName.ldap-login-dn+ldap-login-password: the service account the ASA binds as to perform the user search.server-type microsoft: tells the ASA how to interpret password-expiry and account-locked responses. Other choices includegeneric,sun,openldap.ldap-over-ssl enable+server-port 636: use LDAPS instead of clear-text LDAP. Always use LDAPS in production. Clear LDAP exposes the user's typed password to every device on the inside path between ASA and DC.
Bind to a tunnel-group as the authorization-server-group:
ASA-PERIM(config)# tunnel-group SSL_PROFILE general-attributes
ASA-PERIM(config-tunnel-general)# authorization-server-group LDAP-VPN
This authorizes the user post-authentication: the ASA performs a second LDAP search to retrieve group memberships and attributes, which can be mapped to ASA group-policies via ldap attribute-map. The full attribute-map mechanism is covered in the DAP article (it ties cleanly into Dynamic Access Policies).
Configure TACACS+ for Admin Access
TACACS+ is rarely used for VPN authentication. Its strength is per-command authorization for admins logging into the ASA itself: every CLI command an admin runs is authorized by the TACACS+ server, and every command is logged via accounting.
ASA-PERIM(config)# aaa-server TACACS-ADMIN protocol tacacs+
ASA-PERIM(config)# aaa-server TACACS-ADMIN (inside) host 10.10.0.30
ASA-PERIM(config-aaa-server-host)# key <TACACS_KEY>
ASA-PERIM(config-aaa-server-host)# server-port 49
ASA-PERIM(config-aaa-server-host)# timeout 5
ASA-PERIM(config-aaa-server-host)# exit
Wire into the ASA's admin auth/authz/acct planes:
ASA-PERIM(config)# aaa authentication ssh console TACACS-ADMIN LOCAL
ASA-PERIM(config)# aaa authorization exec authentication-server
ASA-PERIM(config)# aaa accounting ssh console TACACS-ADMIN
What each line does:
aaa authentication ssh console TACACS-ADMIN LOCAL: authenticate SSH logins via TACACS+, fall back to local. Theconsolekeyword here means console-mode SSH (the standard SSH login flow).aaa authorization exec authentication-server: when an authenticated admin enters exec mode, look up their privilege level on the same server that authenticated them. This drives the priv-15 vs priv-1 split.aaa accounting ssh console TACACS-ADMIN: log SSH session start and stop, including duration.
For per-command logging (which most TACACS+ deployments want), add aaa accounting command privilege 15 TACACS-ADMIN to log every priv-15 command. This produces a full audit trail of who-typed-what.
Authentication, Authorization, Accounting Separated
You can mix protocols by feature. A common production pattern:
Each function points at the protocol best suited to it. That is the design configured in the original build of this lab: SSL_PROFILE uses RADIUS for auth + LDAP for authz + RADIUS for acct, while admin SSH uses TACACS+ for all three. In the October 2026 re-test only RADIUS authentication was exercised; LDAP authorization, TACACS+ admin access, LOCAL fallback and accounting were not re-tested.
Common Gotchas
- No LOCAL fallback. RADIUS or LDAP server has an outage, and now no one can log in. Always end the auth chain with
LOCALfor VPN; always end withLOCALfor admin SSH. - Clear-text LDAP. Without
ldap-over-ssl enable, every VPN user's password traverses the inside network in clear-text inside an LDAP bind. Anyone on the path can sniff it. Use LDAPS (TCP/636) or STARTTLS (TCP/389 with negotiated TLS). - Wrong service account permissions. The
ldap-login-dnaccount must have read permission on the user OUs you intend to authenticate against. In AD, a domain user account is typically enough; service accounts often have explicit read-deny on Protected Users group, which breaks lookup. - RADIUS shared-secret typo (or wrong NAS IP). Symptom: a timeout,
ERROR: Authentication Server not responding: No active server found, not a clean reject, and ping can still succeed. In my lab both faults produced exactly that message. Verify withtest aaa-serverand the server log or a capture: a matching config returnsINFO: Authentication Successful, while a wrong password returnsERROR: Authentication Rejected: AAA failure. - Confusing authentication-server-group with authorization-server-group. The two attributes are independent. You can authenticate against RADIUS but authorize against LDAP. If you forget the authorization-server-group, no LDAP attribute-map firing will happen and the user gets the tunnel-group default group-policy regardless of their AD group memberships.
Re-tested in my home lab (October 2026)
Built in my home lab: RADIUS VPN authentication on ASAv 9.24(1) against FreeRADIUS 3.0.27 on Alpine Linux, with Message-Authenticator required on both sides. Direct test aaa-server is the primary proof. OpenConnect 9.12 --authenticate also exercised SSL_PROFILE and received an auth cookie, but there was no AnyConnect image and no VPN data tunnel was established, so AAA success here is not a working tunnel.

Matching configuration
INFO: Attempting Authentication test to IP address (10.58.0.10) (timeout: 5 seconds)
INFO: Authentication SuccessfulWrong password is an immediate reject (distinct from the timeout faults):
INFO: Attempting Authentication test to IP address (10.58.0.10) (timeout: 5 seconds)
ERROR: Authentication Rejected: AAA failureBreak it: wrong NAS IP
Registering FreeRADIUS for 10.58.0.99 while the ASA still sourced from 10.58.0.1 timed out:
INFO: Attempting Authentication test to IP address (10.58.0.10) (timeout: 5 seconds)
ERROR: Authentication Server not responding: No active server foundBreak it: wrong shared secret
Same timeout message — not a reject — with ping still succeeding:
INFO: Attempting Authentication test to IP address (10.58.0.10) (timeout: 5 seconds)
ERROR: Authentication Server not responding: No active server foundFix: restore the matching key
INFO: Attempting Authentication test to IP address (10.58.0.10) (timeout: 5 seconds)
INFO: Authentication SuccessfulLDAP and TACACS+ groups from the article were syntax-probed only (server-type generic was rejected on this image). LDAP runtime, TACACS+ admin authentication, LOCAL fallback, RADIUS accounting and VPN forwarding were not re-tested.
Key Takeaways
AAA on the Cisco ASA is configured in two layers: aaa-server groups (the protocol + hosts), then references to those groups from features (tunnel-groups, admin auth). RADIUS authentication was re-tested on ASAv 9.24(1) with FreeRADIUS: a wrong shared secret or NAS entry timed out with "No active server found" rather than rejecting. LDAP, TACACS+, LOCAL fallback and accounting were not re-tested, and AAA success is not the same as a working VPN tunnel; no data tunnel was tested. Keep a LOCAL fallback on the chains you care about surviving an AAA outage.
For the full Cisco ASA reference, including site-to-site IPsec, NAT, ACLs, failover, and the troubleshooting tools, see the Cisco ASA pillar. The next step after AAA is mapping the AAA-returned attributes (and endpoint posture) to runtime decisions: Cisco ASA Dynamic Access Policies (DAP) covers that. For the connection-profile foundation, see Cisco ASA VPN Group Policies and Tunnel Groups.