-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Independent MFA for infrastructure apps with PIV key #30749
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
asamborski
wants to merge
24
commits into
cloudflare:production
Choose a base branch
from
asamborski:production
base: production
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
20d8a58
Add changelog for browser-based RDP clipboard controls
asamborski cd28486
Merge remote-tracking branch 'upstream/production' into production
asamborski 3f53802
Merge remote-tracking branch 'upstream/production' into production
asamborski 44daef6
Browser-based RDP clipboard control
asamborski b1b3a90
Update changelog date
asamborski eae0d25
Update rdp-browser.mdx
ranbel afdfe31
Apply suggestions from code review
ranbel 8d48938
Apply suggestion from @ranbel
ranbel 5c1999a
Merge remote-tracking branch 'upstream/production' into production
asamborski 43f54c2
Merge remote-tracking branch 'upstream/production' into production
asamborski 4851fd3
Merge remote-tracking branch 'upstream/production' into production
asamborski 2b8179c
Merge remote-tracking branch 'upstream/production' into production
asamborski 0df78ed
Merge remote-tracking branch 'upstream/production' into production
asamborski 1e9caba
Merge remote-tracking branch 'upstream/production' into production
asamborski eb4f722
Merge remote-tracking branch 'upstream/production' into production
asamborski bf94969
Merge remote-tracking branch 'upstream/production' into production
asamborski d5e5664
Merge remote-tracking branch 'upstream/production' into production
asamborski 7ad7ea8
Merge remote-tracking branch 'upstream/production' into production
asamborski 0a82717
Initial commit
asamborski a496ebd
Merge remote-tracking branch 'upstream/production' into production
asamborski d8e25b1
Merge remote-tracking branch 'upstream/production' into asamborski_mf…
asamborski ab03fc7
Proper first draft of PIV key support for infra apps
asamborski 7e3b37a
Merge remote-tracking branch 'upstream/production' into production
asamborski ca86629
Merge remote-tracking branch 'upstream/production' into production
asamborski File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/content/changelog/access/2026-05-15-ssh-mfa-piv-keys.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| --- | ||
| title: Independent MFA for infrastructure applications | ||
| description: Add hardware-backed multi-factor authentication to SSH connections through Access for Infrastructure. | ||
| date: 2026-05-15 | ||
| products: | ||
| - access | ||
| --- | ||
|
|
||
| [Access for Infrastructure](/cloudflare-one/access-controls/applications/non-http/infrastructure-apps/) now supports independent multi-factor authentication (MFA) for SSH connections using YubiKey PIV keys. This adds a hardware-backed second factor to SSH access, ensuring that a compromised device session alone is not sufficient to reach your servers. | ||
|
|
||
| With per-application and per-policy configuration, you can enforce PIV key authentication for sensitive usernames (for example, `root`) while applying different requirements for other usernames. You can also set an MFA session duration to control how often users must re-authenticate. | ||
|
|
||
| ## Enrollment | ||
|
|
||
| Users enroll their YubiKey PIV key through the [App Launcher](/cloudflare-one/access-controls/access-settings/app-launcher/). For enrollment instructions and SSH client setup, refer to [Enroll a PIV key for infrastructure apps](/cloudflare-one/access-controls/access-settings/independent-mfa/#enroll-a-piv-key-for-infrastructure-apps). | ||
|
|
||
| ## Configuration | ||
|
|
||
| For setup instructions, refer to [Enforce MFA for infrastructure applications](/cloudflare-one/access-controls/policies/mfa-requirements/#infrastructure-applications). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,19 +10,20 @@ tags: | |
| - Authentication | ||
| --- | ||
|
|
||
| import { Tabs, TabItem, APIRequest, Details } from "~/components"; | ||
| import { Tabs, TabItem, APIRequest, Details, Render } from "~/components"; | ||
|
|
||
| Independent multi-factor authentication (MFA) allows you to enforce MFA requirements directly in Access without relying on your identity provider (IdP). Users authenticate with their IdP as usual, and Access prompts for an additional authentication method before granting access to the application. | ||
|
|
||
| Because you can [configure MFA at the application and policy level](/cloudflare-one/access-controls/policies/mfa-requirements/#independent-mfa), you can enforce stricter authentication methods like hardware security keys on sensitive applications without requiring them across your entire organization. This allows you to add additional security where it matters most while avoiding MFA fatigue for your broader user population. | ||
|
|
||
| ## Supported MFA methods | ||
|
|
||
| | MFA method | Description | | ||
| | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | Authenticator application | Time-based one-time passwords (TOTP) generated by apps such as Google Authenticator, Microsoft Authenticator, or Authy. Access supports one TOTP authenticator per user at a time. | | ||
| | Security key | YubiKeys and hardware security keys that support the [WebAuthn](https://www.w3.org/TR/webauthn-2/) standard. Users can enroll multiple security keys. | | ||
| | Biometrics | Built-in device authenticators that use [WebAuthn](https://www.w3.org/TR/webauthn-2/), including Apple Touch ID, Apple Face ID, and Windows Hello. Users can enroll multiple biometrics. | | ||
| | MFA method | Description | | ||
| | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | Authenticator application | Time-based one-time passwords (TOTP) generated by apps such as Google Authenticator, Microsoft Authenticator, or Authy. Access supports one TOTP authenticator per user at a time. | | ||
| | Security key | YubiKeys that support the [WebAuthn](https://www.w3.org/TR/webauthn-2/) standard. Users can enroll multiple security keys. | | ||
| | Biometrics | Built-in device authenticators that use [WebAuthn](https://www.w3.org/TR/webauthn-2/), including Apple Touch ID, Apple Face ID, and Windows Hello. Users can enroll multiple biometrics. | | ||
| | PIV key (infrastructure apps only) | YubiKey PIV keys used for public key authentication during SSH connections. Requires YubiKey firmware 4.3 or later. This method is only available for [infrastructure applications](/cloudflare-one/access-controls/applications/non-http/infrastructure-apps/). Users can enroll multiple PIV keys. | | ||
|
|
||
| ## Turn on independent MFA | ||
|
|
||
|
|
@@ -79,6 +80,29 @@ Before you can [enforce independent MFA on applications and policies](/cloudflar | |
|
|
||
| After you turn on independent MFA, users can [enroll authenticators](#enroll-authenticators) through the [App Launcher](/cloudflare-one/access-controls/access-settings/app-launcher/). | ||
|
|
||
| ### Configure PIV key requirements | ||
|
|
||
| If you plan to use PIV keys for [MFA for infrastructure applications](/cloudflare-one/access-controls/policies/mfa-requirements/#infrastructure-applications), configure the PIV key requirements in your organization's Access settings. These requirements determine which PIV keys users can enroll. | ||
|
|
||
| 1. In the [Cloudflare dashboard](https://dash.cloudflare.com/), go to **Zero Trust** > **Access controls** > **Access settings**. | ||
| 2. Under **Allow multi-factor authentication (MFA)**, turn on the PIV key authenticator. | ||
| 3. Configure the following settings: | ||
|
|
||
| | Setting | Description | Options | | ||
| | ---------------- | ----------------------------------------- | --------------------------------------------------------------- | | ||
| | **Key type** | The SSH key algorithm | ECDSA, Ed25519, RSA | | ||
| | **Key size** | The key length in bits | ECDSA: 256, 384, 521. RSA: 2048, 3072, 4096 | | ||
| | **PIN policy** | When the user must enter their PIV PIN | `never`, `once` (once per session), `always` (every use) | | ||
| | **Touch policy** | When the user must touch the hardware key | `never`, `always` (every use), `cached` (cached for 15 seconds) | | ||
|
|
||
| 4. Select **Save**. | ||
|
|
||
| Enrolled PIV keys that do not meet these requirements are rejected during SSH authentication. | ||
|
|
||
| :::note | ||
| <Render file="access/piv-key-global-settings-warning" product="cloudflare-one" /> | ||
| ::: | ||
|
|
||
| ## Restrict authenticators by AAGUID | ||
|
|
||
| An [AAGUID](https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-registry-v2.0-id-20180227.html#authenticator-attestation-guid) (Authenticator Attestation GUID) is a 128-bit identifier that indicates the make and model of a [WebAuthn](https://www.w3.org/TR/webauthn-2/) authenticator. By restricting enrollment to a specific set of AAGUIDs, you can require that users only enroll approved hardware, such as FIPS-validated security keys or company-issued devices. | ||
|
|
@@ -196,8 +220,8 @@ If your identity provider already prompts users for MFA, you can configure Acces | |
|
|
||
| ### Supported AMR values | ||
|
|
||
| | AMR value | Matches Access authenticator type | Description | | ||
| | --------- | --------------------------------- | -------------------------------------- | | ||
| | AMR value | Matches Access authenticator type | Description | | ||
| | --------- | --------------------------------- | ------------------------------------- | | ||
| | `hwk` | Security key | Proof-of-possession of a hardware key | | ||
| | `swk` | Security key | Proof-of-possession of a software key | | ||
| | `otp` | Authenticator application | One-time password | | ||
|
|
@@ -339,8 +363,13 @@ To enroll an authenticator: | |
| </Details> | ||
|
|
||
| <Details header="Security key"> | ||
|
|
||
| :::note | ||
| Access currently supports YubiKeys as the only hardware security key. | ||
| ::: | ||
|
|
||
| 1. Select **Security key**. | ||
| 2. When your browser prompts you, insert your security key and follow the on-screen instructions. | ||
| 2. When your browser prompts you, insert your YubiKey and follow the on-screen instructions. | ||
| 3. After your browser confirms the registration, the security key is enrolled. | ||
|
|
||
| You can enroll multiple security keys for backup purposes. | ||
|
|
@@ -354,8 +383,97 @@ To enroll an authenticator: | |
|
|
||
| </Details> | ||
|
|
||
| <Details header="PIV key (infrastructure applications only)"> | ||
| PIV key enrollment requires additional client-side setup and is only used for [MFA with infrastructure applications](/cloudflare-one/access-controls/policies/mfa-requirements/#infrastructure-applications). For full instructions, refer to [Enroll a PIV key for infrastructure apps](#enroll-a-piv-key-for-infrastructure-apps). | ||
| </Details> | ||
|
|
||
| You can now use these authenticators to log in to your organization's applications. | ||
|
|
||
| ### Enroll a PIV key for infrastructure apps | ||
|
|
||
| PIV key enrollment is separate from the general authenticator enrollment above and requires additional client-side setup. | ||
|
|
||
| Before enrolling, you must have a YubiKey with firmware 4.3 or later and a key generated in PIV slot `9a`. If you have not generated a PIV key yet, refer to [Generate a PIV key](#generate-a-piv-key). | ||
|
|
||
| #### Generate attestation certificates | ||
|
|
||
| Attestation certificates prove that the key was generated on genuine hardware. Run the following commands to export them from your YubiKey: | ||
|
|
||
| ```bash | ||
| ykman piv keys attest 9a leaf.pem | ||
| ykman piv certificates export f9 intermediate.pem | ||
| ``` | ||
|
|
||
| - `leaf.pem` contains the public key and metadata for the key in slot `9a`. | ||
| - `intermediate.pem` is the YubiKey attestation CA certificate. | ||
|
|
||
| #### Upload certificates to Cloudflare | ||
|
|
||
| 1. Go to your organization's App Launcher at `<your-team-name>.cloudflareaccess.com`. | ||
| 2. Log in with your identity provider or with a one-time PIN (OTP). | ||
| 3. Go to **Account** > **MFA devices** > **Add an MFA device**. | ||
| 4. Select **MFA PIV Key**. | ||
| 5. Paste the contents of `leaf.pem` into the **Leaf certificate** field. | ||
| 6. Paste the contents of `intermediate.pem` into the **Intermediate certificate** field. | ||
| 7. Select **Enroll**. | ||
|
|
||
| Access extracts and stores the SSH public key from your certificate for future authentication to infrastructure apps. You can enroll multiple PIV keys for backup purposes. | ||
|
|
||
| #### Configure your SSH client | ||
|
|
||
| After enrollment, configure your SSH client to use the PIV key. The following example uses `yubikey-agent` on macOS. For Linux, refer to the [yubikey-agent documentation](https://github.com/nicholasgasior/yubikey-agent). | ||
|
|
||
| 1. Install and start `yubikey-agent`: | ||
|
|
||
| ```bash | ||
| brew install yubikey-agent | ||
| brew services start yubikey-agent | ||
| ``` | ||
|
|
||
| 2. Extract the SSH public key from your leaf certificate: | ||
|
|
||
| ```bash | ||
| openssl x509 -in leaf.pem -pubkey -noout | ssh-keygen -i -m PKCS8 -f /dev/stdin > ~/.ssh/id_yubikey.pub | ||
| ``` | ||
|
|
||
| 3. Add the following to your `~/.ssh/config`: | ||
|
|
||
| ```txt | ||
| Host * | ||
| IdentityAgent /opt/homebrew/var/run/yubikey-agent.sock | ||
| IdentitiesOnly yes | ||
| AddKeysToAgent yes | ||
| IdentityFile ~/.ssh/id_yubikey.pub | ||
| ``` | ||
|
|
||
| 4. Verify that the key is loaded: | ||
|
|
||
| ```sh | ||
| ssh-add -L | ||
| ``` | ||
|
|
||
| The output should show an `ecdsa-sha2-nistp256` key. | ||
|
|
||
| #### Generate a PIV key | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section should be above the |
||
|
|
||
| If you do not already have a PIV key on your YubiKey, generate one in slot `9a`: | ||
|
|
||
| ```bash | ||
| ykman piv keys generate \ | ||
| --algorithm ECCP256 \ | ||
| --pin-policy ONCE \ | ||
| --touch-policy ALWAYS \ | ||
| 9a pubkey.pem | ||
| ``` | ||
|
|
||
| Touch your YubiKey when it blinks to confirm key generation. Then create a self-signed certificate to make the key visible to SSH agents: | ||
|
|
||
| ```bash | ||
| ykman piv certificates generate --subject "CN=SSH-Identity" 9a pubkey.pem | ||
| ``` | ||
|
|
||
| After generating the key, [generate attestation certificates](#generate-attestation-certificates) and continue with enrollment. | ||
|
|
||
| ### Delete an authenticator | ||
|
|
||
| Users can delete their own authenticators from the App Launcher. If the user has at least one authenticator enrolled, Access requires them to [verify with an existing MFA method](#mfa-verification-for-authenticator-changes) before they can remove a device. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The leaf and intermediate cert upload will fail in the app launcher if they don't meet the requirements. If the user is able to successfully save that page, then their PIV key is valid (in accordance to the requirements).