gravitational/teleport · error

cannot fulfill authenticator attachment %q

Error message

cannot fulfill authenticator attachment %q

What it means

The Touch ID authenticator implementation in Teleport only supports the platform attachment (Touch ID / Secure Enclave). When a WebAuthn credential creation request (PublicKeyCredentialCreationOptions) specifies AuthenticatorAttachment of CrossPlatform (e.g. roaming security keys), it cannot be fulfilled and Register fails with this error. It is an early sanity check before building the platform authenticator request.

Source

Thrown at lib/auth/touchid/api.go:251

	if origin == "" {
		return nil, trace.BadParameter("origin required")
	}
	if err := cc.Validate(); err != nil {
		return nil, trace.Wrap(err)
	}

	// Ignored cc fields:
	// - Timeout - we don't control touch ID timeouts (also the server is free to
	//   enforce it)
	// - CredentialExcludeList - we always allow re-registering (for various
	//   reasons).
	// - Extensions - none supported
	// - Attestation - we always to our best (packed/self-attestation).
	//   The server is free to ignore/reject.

	if cc.Response.AuthenticatorSelection.AuthenticatorAttachment == protocol.CrossPlatform {
		return nil, fmt.Errorf("cannot fulfill authenticator attachment %q", cc.Response.AuthenticatorSelection.AuthenticatorAttachment)
	}
	ok := false
	for _, param := range cc.Response.Parameters {
		// ES256 is all we can do.
		if param.Type == protocol.PublicKeyCredentialType && param.Algorithm == webauthncose.AlgES256 {
			ok = true
			break
		}
	}
	if !ok {
		return nil, errors.New("cannot fulfill credential parameters, only ES256 are supported")
	}

	rpID := cc.Response.RelyingParty.ID
	user := cc.Response.User.Name
	userHandle := cc.Response.User.ID

	// TODO(codingllama): Handle double registrations and failures after key

View on GitHub (pinned to 1283425b60)

Solutions

  1. Set AuthenticatorSelection.AuthenticatorAttachment to protocol.Platform (or leave it unset/auto) when the request may be served by Touch ID.
  2. Configure the Teleport server's WebAuthn settings so attachment is not pinned to cross-platform for macOS clients.
  3. If cross-platform keys are genuinely required, use a different client path (e.g. webauthncli/FIDO2) instead of the Touch ID API.
  4. Update tests to use Platform attachment when exercising the Touch ID register flow.

Example fix

// before
cc.Response.AuthenticatorSelection.AuthenticatorAttachment = protocol.CrossPlatform
cred, err := api.Register(cc)
// after
cc.Response.AuthenticatorSelection.AuthenticatorAttachment = protocol.Platform
cred, err := api.Register(cc)
Defensive patterns

Strategy: validation

Validate before calling

if cc != nil && cc.Response.AuthenticatorSelection.AuthenticatorAttachment == protocol.CrossPlatform {
    return errors.New("touchid API cannot serve cross-platform authenticators; use platform attachment")
}

Type guard

func touchIDCanFulfill(cc *protocol.CredentialCreation) bool {
    return cc == nil || cc.Response.AuthenticatorSelection.AuthenticatorAttachment != protocol.CrossPlatform
}

Try / catch

cred, err := api.Register(cc)
if err != nil {
    if strings.Contains(err.Error(), "cannot fulfill authenticator attachment") {
        // fall back to the FIDO2/roaming-key path
        return fallbackFIDO2Register(cc)
    }
    return trace.Wrap(err)
}

Prevention

When it happens

Trigger: Calling touchid Register (directly or via promptTouchIDRegisterChallenge) with a creation options object whose AuthenticatorSelection.AuthenticatorAttachment is set to protocol.CrossPlatform.

Common situations: Server-side WebAuthn configuration that requests cross-platform (USB/NFC) authenticators while the client is the macOS Touch ID path; test code (TestRegister_rollback, TestLogin_*) passing crafted options; shared WebAuthn settings not differentiated per platform.

Understand the failure class

Related errors


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/f89a9b38befdd05f. Report an issue: GitHub.