Skip to main content
INS // Insights

VPN Access Review Tied to Last Login

Updated October 2026 · 7 min read

A vpn access review starts from the people who can still open the corporate tunnel, joined to the last time that tunnel actually came up. The corporate VPN group is the entitlement. The last successful connection is the only usage fact that belongs on the same row. Mid-market teams still export the group to a spreadsheet and ask managers to remember who connected. The auditor then samples a contractor who is still entitled, and nobody can show a session.

Rutagon builds that join and files the pack in the GRC platform you already run. The client is the one in the audit. Rutagon builds the evidence pipeline. A person still decides keep or remove. The pipeline stops the reconstruction from chat logs and memory.

The population is the VPN group

The population is membership in the group your identity provider uses to authorize the tunnel, expanded through nested groups, at export time. The group may be named for the network, a vendor, or a legacy project. We use the name already written in the system description. A person who connected and is not in the group is a different exception: use without entitlement. A person who is in the group and has no successful connection inside the review window is the stale entitlement this review exists to show.

Contractors sit in the same export. Engagement end dates are tracked in the contractor and vendor access review. This article is the tunnel. If the engagement ended and the group still lists the person, the row stays open here. The two extracts do not share a clock unless we put both facts on one review.

Directory status is a column, not a filter that hides people. A member who is suspended in the directory and still in the VPN group is still entitled. Suspension in one system does not revoke the other. That split shows up only when both facts share a row. Dropping suspended users from the export makes the sample look clean and leaves the tunnel in place.

VPN access review rows we file

Every member produces one row. The workforce id is filled after we map the VPN identifier to the directory. Membership is marked direct or nested, and the nested path is kept so the reviewer edits the group that actually grants the tunnel. Directory status is the status at export time. Last successful connection is a timestamp or an explicit empty value. The log source and the join field are on the row. The decision stays empty until a person records it.

An empty last-success is a value. We do not omit the row because the log search returned nothing. Omitting it is how stale members vanish before the sample. The pack in the quarterly access review automation guide can consume this export. The VPN row is one system inside that pack.

The join key is the identifier the concentrator actually logs. On an AWS Client VPN endpoint that uses directory or SAML authentication, connection logs include username, and a successful attempt sets connection-attempt-status to successful. AWS documents those fields in connection logging for Client VPN. We take the latest connection-start-time among successful attempts inside the review window. A failed attempt, including one denied by an authorization policy, is not successful use. When the log carries the deny, we can park it beside the row. It does not clear the empty success time.

Certificate-only endpoints log common-name and do not log username. We keep a map from that common name to a workforce id. An unmapped common name stays on the sheet as unmapped. Failed mutual authentication attempts are not written to this log, so the review is entitlement plus successful use. It is not a complete history of rejected handshakes. If that history matters, it has to come from another source, and we will not pretend this log contains it.

workforce_id: mapped-or-unmapped
vpn_group: corporate-vpn
membership: direct-or-nested
last_success_at: empty-or-log-time
join_field: username-or-common-name
attempt_status: successful
decision: pending

The timestamp comes from the log. It does not come from a laptop clock, and it does not come from the directory's last password change. Password change is not tunnel use. Reviewers paste a directory timestamp into a "last VPN login" column because it was the only date the directory export offered. That column then disagrees with the concentrator the moment someone asks for the log.

The log also carries client-vpn-endpoint-id. Companies with more than one endpoint get one row per membership per endpoint, not a single blended "last login" that hides which tunnel still works. A success on the lab endpoint does not prove use of the production tunnel.

Name drift and nested paths

Nested membership is in scope. A person in a department group that sits inside the VPN group is entitled. A review that expands only the first level certifies a short list while the nested group still holds a departed contractor. We expand to the leaves and we record the path. Removing the person from the wrong group leaves the tunnel.

Name drift is the other break. The directory, the SAML assertion, and the certificate common name are three strings. The map is a table with an owner. A fuzzy match that joins two people hides a stale member under someone else's last success. An unmapped row is louder and safer. The first export after an assertion change is full of unmapped rows. That output is correct. Closing those rows because the strings look similar is the shortcut we refuse.

Authorization-policy context is optional on the endpoint and defaults off. We do not block the review on that setting. When a policy result is present, permit and deny are labels on the attempt. Only a successful connection fills last_success_at.

What the reviewer decides

The sheet arrives in three piles. Entitled, with a successful connection inside the window: does this person still need the tunnel? Entitled, with no successful connection inside the window: remove, or record a reason the access must remain. A connected identifier with no group membership: explain how the tunnel was authorized. That third pile does not receive a "keep" on the group review.

A reason to keep a stale member names a person and a date to look again. A standing "break glass" with no owner leaves the row open. The pipeline does not invent the reason. Removal is a ticket back to the identity provider. We store the ticket id on the row. The next export either drops the member or the row reopens. A sign-off PDF while the following export still shows the member is an open review.

Filing and the cadence

The export runs on the cadence you already promised, and it can run between decision cycles so the success time is fresh when the reviewer opens the sheet. Extra exports do not create extra signatures. Only the decision cycle creates reviewer work.

Filing is an API call or a structured upload into the GRC you already run, on the access-review control you already named. The ticket id comes back onto the pack. When the GRC cannot store structured fields, we attach the same file and keep the ticket id. The shape stays stable so the next window is the same export.

This collector sits with the security automation we build for entitlement exports. The concentrator stays yours. We read the group and the success log, and we write the row. Rutagon's own tunnels follow the same shape: a group, a mapped identity, a success time from the log. That is engineering practice. It is not an attestation anyone else can borrow.

Frequently Asked Questions

Which accounts belong in a vpn access review?

The population is everyone still in the corporate VPN group, including people who arrive through a nested group. Connected users who are outside the group are a separate exception. We do not start from a list of recent sessions and hope the entitlement matches.

Which log field counts as a successful connection?

On AWS Client VPN with directory or SAML authentication, we use a connection attempt whose status is successful and we read the username. Certificate-only endpoints are joined on the certificate common name through a maintained map. A denied attempt does not fill the last-success time.

Why is an empty last-success still a row?

The person remains entitled. Dropping the row because the log search was empty hides the stale member from the sample. The reviewer needs that row to remove the membership or to record an owner and a follow-up date.

How do suspended directory users show up?

They stay on the export when the VPN group still lists them. Directory suspension is a column. It does not revoke the tunnel by itself. The row stays open until the group membership is actually gone on the next export.

Where does the reviewer sign?

In the GRC you already run. We upload the pack and store the ticket id on the export. The identity provider is where removal happens. The following export is the check that the removal landed.

See what an Access & Credential Governance Diagnostic finds in your environment. Contact Rutagon at rutagon.com/contact, 907-841-8407, or contact@rutagon.com.