gravitational/teleport · error
cred required for %q ceremony
Error message
cred required for %q ceremony
What it means
makeAttestationData builds the WebAuthn attestation response for a Touch ID ceremony. A Create (registration) ceremony inherently needs the newly generated credential data (credential ID, public key, etc.); if the cred argument is nil for a create ceremony, the function refuses rather than producing an invalid attestation object. Login ceremonies may legitimately pass nil, so only CreateCeremony is checked.
Source
Thrown at lib/auth/touchid/api.go:396
type attestationResponse struct {
ccdJSON []byte
rawAuthData []byte
digest []byte
}
// TODO(codingllama): Share a single definition with webauthncli / mocku2f.
type collectedClientData struct {
Type string `json:"type"`
Challenge string `json:"challenge"`
Origin string `json:"origin"`
}
func makeAttestationData(ceremony protocol.CeremonyType, origin, rpID string, challenge []byte, cred *credentialData) (*attestationResponse, error) {
// Sanity check.
isCreate := ceremony == protocol.CreateCeremony
if isCreate && cred == nil {
return nil, fmt.Errorf("cred required for %q ceremony", ceremony)
}
ccd := &collectedClientData{
Type: string(ceremony),
Challenge: base64.RawURLEncoding.EncodeToString(challenge),
Origin: origin,
}
ccdJSON, err := json.Marshal(ccd)
if err != nil {
return nil, trace.Wrap(err)
}
ccdHash := sha256.Sum256(ccdJSON)
rpIDHash := sha256.Sum256([]byte(rpID))
flags := byte(protocol.FlagUserPresent | protocol.FlagUserVerified)
if isCreate {
flags |= byte(protocol.FlagAttestedCredentialData)
}View on GitHub (pinned to 1283425b60)
Solutions
- Ensure the Touch ID Register flow creates credentialData (via Secure Enclave key generation) before calling makeAttestationData.
- Pass the non-nil *credentialData returned by the key-creation step into makeAttestationData for CreateCeremony.
- If you hit this after refactoring, audit that the credential generation error is not being swallowed upstream.
- For Login ceremonies, pass nil cred intentionally — no fix needed there.
Example fix
// before
resp, err := makeAttestationData(protocol.CreateCeremony, origin, rpID, challenge, nil)
// after
cred, err := createSecureEnclaveCredential(rpID, user)
if err != nil { return nil, trace.Wrap(err) }
resp, err := makeAttestationData(protocol.CreateCeremony, origin, rpID, challenge, cred) Defensive patterns
Strategy: validation
Validate before calling
if ceremony == protocol.CreateCeremony && cred == nil {
return errors.New("registration ceremony requires credential data from Secure Enclave key creation")
} Type guard
func hasCredentialForCeremony(ceremony protocol.CeremonyType, cred *credentialData) bool {
return ceremony != protocol.CreateCeremony || cred != nil
} Try / catch
resp, err := makeAttestationData(ceremony, origin, rpID, challenge, cred)
if err != nil {
if strings.Contains(err.Error(), "cred required") {
return nil, trace.Wrap(err, "register flow failed to create credential; check Secure Enclave key generation")
}
return nil, trace.Wrap(err)
} Prevention
- Always generate and propagate credentialData before building the attestation response.
- Do not swallow errors from Secure Enclave key creation.
- Cover Register with a test asserting cred != nil at the makeAttestationData call site.
When it happens
Trigger: Calling makeAttestationData (via Register or Login) with ceremony == protocol.CreateCeremony while passing cred == nil — i.e. the register flow failed to produce or store credentialData before building the attestation response.
Common situations: A bug or modified code path in the Touch ID Register flow where Secure Enclave key generation failed silently or credentialData was not threaded through; tests invoking makeAttestationData directly with missing arguments.
Related errors
- credential not found
- touch ID not available
- cannot fulfill credential parameters, only ES256 are support
- cannot fulfill authenticator attachment %q
- user has only invalid WebAuthn registrations, consider a use
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/00b2bc4f29768f62.
Report an issue: GitHub.