Summary

  • A COSE kid is an unstructured, non-unique hint for finding candidate keys. It can be carried outside the protected header because the cryptographic decision must rest on the actual key and signed inputs, not on the hint.
  • A defensible verification record preserves the lookup namespace, every candidate key, the fingerprint that verified, the exact protected bytes, identity binding, authorization policy and downstream result as separate evidence.

Imagine a small verifier receiving a COSE_Sign1 message. Its unprotected header carries kid = 0x19. A local table returns two keys: one retained for rotation and one provisioned for a different tenant. The first fails; the second verifies. Which identity signed the message?

The answer is not 0x19. That byte is useful, but it has not named one key, much less a person or device. If the application stores only “kid 0x19 verified”, it has discarded the candidate set, the successful key and the namespace that made the lookup possible. A later investigator cannot tell whether the event reflects planned rotation, a cross-tenant collision, stale provisioning or a faulty search order.

This is a hypothetical failure of record design, not a reported COSE incident. Its rules come from a specification that is unusually explicit about where shorthand stops.

The identifier filters; it does not decide

RFC 9052 defines the current COSE structures and process. Its common header table assigns kid integer label 4 and a byte-string value. The prose then removes any invitation to treat that field as a universal primary key. A kid supplies one piece of data that can help find the cryptographic key. It may match the corresponding member in a COSE_Key or an equivalent field defined by another distribution method.

Applications are told not to assume uniqueness. More than one key can carry the same value, so all associated keys may need to be checked. The bytes have no standard internal structure on which an application may rely. In a COSE_Key, the value can be a user-chosen string or something computed from the public key, yet it may still recur in another object representing a different key.

The engineering noun is therefore “filter”. A lookup begins with an application, an issuer or tenant, a store version, a time and the received bytes. It returns a candidate set. Only after a cryptographic operation succeeds can one candidate be identified as the verification key. Even then, the result belongs to that full key, not retroactively to every key sharing the hint.

The IANA COSE registry preserves this narrow wire meaning: kid is a byte-string key identifier. It also registers a separate kid context parameter. That does not require every application to use the context field, but it makes the general lesson visible in the registry itself: a short identifier may need a declared scope before it becomes useful.

Unprotected is a deliberate clue

COSE requires both protected and unprotected header buckets. Protected parameters enter the authenticated construction. Unprotected parameters travel with the object but are not thereby covered by that protection. Some fields, such as the algorithm when protection is available, carry security meaning and must be authenticated.

kid is treated differently. RFC 9052 calls it a hint and says it is not security-critical; for that reason it may be placed in the unprotected bucket. This is not a statement that lookup behavior is operationally harmless. An altered hint can waste work, select the wrong candidate set, cross a badly designed namespace or produce an ambiguous audit line. It means the receiver must never grant security meaning to the hint itself.

If an attacker changes an unprotected kid, the replacement does not manufacture a valid signature under an unrelated key. Verification still has to succeed with an actual candidate over the exact signed construction. The defensible response is neither to trust the label nor to declare the whole format broken. It is to bound lookup cost, isolate namespaces, retain every candidate examined and let cryptographic verification identify the key that actually worked.

The signature has an exact subject

The verification input is not a dashboard label. RFC 9052 constructs a Sig_structure containing a context string, the protected body parameters, protected signer parameters where the structure has them, externally supplied authenticated data and the complete payload. That structure is encoded into the ToBeSigned byte string. The verification algorithm receives those bytes, an algorithm, an actual key and the signature.

A receipt should therefore identify the COSE structure and preserve the protected-header bytes rather than only a decoded map. It should state how external authenticated data was obtained, hash the payload as processed, name the algorithm after policy checks and record the full fingerprint and provenance of each key tried. Parser version and rejection reasons matter when multiple encodings, malformed maps or unsupported critical parameters can stop processing before signature mathematics begins.

This separation also prevents a common forensic shortcut. “Signature valid” is a result over a precise tuple. It does not mean that every field shown beside the message was authenticated. If kid came from the unprotected bucket, the UI must not place it inside the visual boundary of the signature without saying so.

Identity and authority start after verification

RFC 9052 does not end its verification procedure with the mathematical pass. It instructs the application to make the appropriate checks that the key is correctly paired with the signing identity and that the identity is authorized before any action is performed.

Those are two different joins. A certificate, provisioning receipt, hardware attestation, account record or locally governed binding may connect the verified key to an identity. A separate policy decides whether that identity may perform this operation now, on this resource, under this application version. Neither fact is carried by the four-byte header label kid.

The difference becomes material during rotation. Old and new keys may deliberately share a convenient hint while both are accepted for a grace period. One key may verify an archived message but no longer authorize a new command. Revocation can change the current policy without changing the historical signature result. A signer can be authentic yet outside the requested role, or authorized in one tenant and unknown in another.

The event model must keep those clocks apart: observation time, key-store snapshot, verification time, identity-binding validity, policy decision time and application commit. Overwriting them with a single green check turns a reconstructable chain into an assertion no one can audit.

An application supplies the missing jurisdiction

COSE deliberately provides security structures without imposing one universal deployment profile. Section 10 of RFC 9052 leaves each application to choose the message types, security services, header parameters, algorithms and any negotiation or discovery method it needs. That is not an omission to be repaired by guessing. It is where local protocol responsibility begins.

RFC 9200 offers a concrete example in the ACE OAuth framework. In an authorization-server response carrying a proof-of-possession COSE_Key, it says kid is only for simplifying key indexing and retrieval and must not be assumed unique in either the client or Resource Server domain. Even a profile concerned directly with access tokens refuses to turn the hint into authorization.

The application receipt consequently needs the profile name and version, the lookup domain, issuer or authorization server, audience or resource server, applicable key-use restrictions and policy decision. A verifier that cannot state those inputs has not completed the identity and authority work just because the cryptography returned true.

Schaad’s place in the record

Jim Schaad authored the original 2017 COSE specification, RFC 8152. RFC 9052, whose author block also names J. Schaad, later replaced its structures portion while RFC 9053 separated the algorithms. The IETF Datatracker profile connects him to a much wider RFC record. These are IETF consensus documents, not personal commands, and authorship does not make Schaad the operator or security authority for any implementation.

A public Oregon Wine Press remembrance records another part of the person and provides the credited photograph used to ground the accompanying editorial portrait. The vineyard image is identity provenance, not technical evidence. The technical value here lies in the specification’s refusal to let a convenient label absorb the responsibilities of key selection, verification, identity and policy.

Preserve the losing candidates

A useful record does not begin with “verified”. It begins with receipt of a particular COSE object. Store its content hash, structure type, raw protected bytes, unprotected parameters, external-data recipe and payload reference. Then store the lookup query as a scoped object: application, tenant or issuer, key-store version, received kid, time and candidate count.

For every candidate, retain a stable full-key fingerprint, source, validity interval, permitted operations and verification outcome. If one succeeds, create a separate verification record pointing to that fingerprint and the exact ToBeSigned hash. Then attach, without merging, the identity-binding evidence, authorization policy and downstream action receipt.

The failed candidates are not noise. They explain why search order changed, why a rotation window produced two answers, why one deployment passed while another failed and whether a supposed duplicate was visible at the relevant time. They also stop a later export from presenting the compact hint as if it had always named the successful key.

The final statement can then be exact: this object was verified with this key over these bytes; this evidence bound the key to this identity; this policy allowed or denied this action; this system observed this result. kid remains in the record, doing the modest job Schaad’s specification gave it.

Sources