Contractor ZTNA to an SSH bastion with posture checks
Three hundred remote users reach an internal ERP application through FortiGate ZTNA (destination host erp.corp.example.com at 10.50.1.20:443) and an SSH bastion at 10.50.2.30:22. FortiClient 7.4 is registered to EMS 7.4, which is integrated with the FortiGate so that EMS issues zero trust tags consumed in FortiGate policy. Employees reach ERP after a user credential check. A group of 60 contractors must reach the SSH bastion only, and only when their company-managed Windows laptop is compliant: real-time antivirus running, operating system build current, disk encryption enabled. Contractors work from their own home networks. Symptoms: a contractor laptop reimaged with a known-good build still cannot reach SSH 30 minutes later; several employees on unstable Wi-Fi lose access for a few minutes and then recover; and a handful of contractors on older Windows 10 builds show a failed check even though antivirus is running.
1. Design the tag structure and the FortiGate policy logic for the contractor requirement, and explain why you would not reuse a single general-purpose compliance tag.
Read the worked answer
Separate identity from posture, and keep tags narrowly meaningful.
Tag building blocks in EMS: create individual zero trust tags for each posture condition (antivirus real-time protection active, OS build at or above the approved level, disk encryption on) and then one aggregate tag, for example ctr-posture-ok, whose rule requires all three. Building blocks make failures diagnosable: when a contractor is denied you can see which condition failed instead of a single opaque tag.
FortiGate logic: the SSH rule's source must require both the contractor identity group and ctr-posture-ok, with destination scoped to the ZTNA destination for the bastion. No ERP rule should list the contractor group at all - deny by omission rather than by exception.
Why not one shared tag: a generic tag such as compliant is likely to be true for employees too. The day someone edits the SSH policy source and picks the tag without the group, every employee gets bastion access, and the error is invisible because the tag reads as legitimate. Purpose-scoped tags and AND-ing them with identity mean a single policy mistake cannot widen access.
Finally, confirm the FortiGate actually receives tags: the EMS fabric connection must be up and the tag must appear in the FortiGate's ZTNA tag list before you test the policy. A correct rule referencing a tag that never arrives denies everything.
2. Diagnose why the reimaged laptop still fails after 30 minutes, and sequence the checks.
Read the worked answer
A reimaged laptop is a new FortiClient identity. It registers again, which can create a new endpoint record while the old record and its tags linger. Until the new record is evaluated by the tag rule and that result reaches the FortiGate, the device cannot match the policy - and if the evaluation is failing, waiting will not help.
Check in this order:
- EMS endpoint inventory: is there a record for this device with a recent last-seen time? Is it the new record, and is the old record still present holding a stale tag? Delete the stale record so a tag for a machine that no longer exists cannot keep a policy looking healthy.
- Tag rule evaluation: does the rule match this endpoint? Most failures here are definitional - a build string that does not match your "current build" expression, or disk-encryption status not being read on that hardware or Windows edition.
- Group and profile: is the endpoint in the group whose profile enables the posture checks? Compliance data comes from the profile; no profile means no data, so the tag rule evaluates against nothing.
- FortiGate: is the ZTNA tag present in the FortiGate's tag list and is the fabric connection to EMS up? Also check whether the FortiGate is still holding an older tag state for that user.
- FortiClient logs on the endpoint for registration and tag-reporting errors.
Use the same sequence for the contractors on older Windows 10 builds: the cause is almost certainly an over-strict build expression or a Windows edition that does not report encryption the way the rule expects.
3. Explain the intermittent access loss on unstable Wi-Fi and describe how you would design the ZTNA access to be robust without abandoning deny-by-default.
Read the worked answer
Access depends on two live relationships: the FortiClient-to-FortiGate tunnel and the FortiClient-to-EMS channel that keeps device state and tags current. On flaky Wi-Fi or a hotel NAT that times out, the EMS channel drops first. State stops refreshing; the FortiGate eventually treats the tag as stale or absent, the policy stops matching, and the connection fails. When connectivity returns, re-registration and tag refresh restore access - which matches the observed few-minutes outage followed by recovery.
Design changes, in order of impact:
- Reachability: expose EMS on a stable public FQDN and port reachable from residential networks, and keep NAT timeouts on the internet edge long enough that an idle client does not lose its session. Most "random" tag loss is actually reachability.
- Stable tag conditions: build rules on conditions that do not flap. A rule like "signature updated within the last hour" will oscillate on any endpoint whose update fails; a daily-threshold rule with a tolerance window behaves far better and still means something.
- Destination by name: reference the ZTNA destination by FQDN so network changes and captive portals do not break the tunnel target.
- Documented fallback: if the business cannot tolerate denial during an EMS outage, provide a separate, tightly scoped emergency path (for example a VPN portal with MFA, restricted to the ERP web app only) rather than loosening the ZTNA tag rule. Log and alert on its use, and review the volume monthly - a fallback that is used daily has become the primary path without anyone deciding that.