trusting the team_id codesign naming scheme?

I have a question about the amount of trust I should have in the team_id for an executable.

I've been looking at the signing_id and team_id values in Apple's endpoint es_process_t, and almost all code follows the reverse naming scheme for their team_id. They have names like:

  • com.getdropbox.dropbox
  • com.microsoft.teams.helper
  • com.apple.mdworker_shared
  • com.apple.spctl

But Google (at least) violates this reverse DNS pattern when signing many of their binaries. They have team IDs such as

  • ksfetch
  • GoogleSoftwareUpdateDaemon
  • crashpad_handler

Should I not trust the TLD (e.g., com.apple or com.microsoft) for the team ID?

For example, could Google (or a malicious organization) sign their binary com.microsoft.ksfetch making me think it came from Microsoft?

Answered by DTS Engineer in 750164022

You seem to be mixing up Team ID and code signing identifier. A Team ID is a short alphanumeric string allocated by Apple. For example, the one for my individual test team is SKMME9E2Y8. You can trust these, in this sense that you can be sure that:

  • Once Apple has issued a Team ID to a team, we won’t issue that same Team ID to any other team.

  • Only appropriately authorised members of that team can ship code signed with that Team ID [1].

In contrast, a code signing identifier is a way to uniquely identify code within a team [2]. It’s assigned by the team however they want. It’s traditional for bundled code to use the bundle ID as the code signing identifier. For example, a test app from DTS might have a bundle ID of com.example.apple-samplecode.Test727901 and have that same value as its code signing identifier. However, that’s not required. It’s common for you to encounter all sorts of weird values here, especially for code that’s not in a bundle.

Note In Creating Distribution-Signed Code for Mac I offer specific advice on how to set this for non-bundled code (search the doc for pig-jato to find it) but there’s absolutely no requirement for folks to follow that advice.

Apple generally identifies code using its designated requirement. For third-party code this typically includes both the Team ID and the code signing identifier. See TN3127 Inside Code Signing: Requirements for all the details.

Oh, and all of the above is about the Mac, and specifically Developer ID signed code on the Mac. If the code ships via an App Store, Apple applies further checks.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Modulo security breaches, of course |-:

[2] In theory this is more subtle but this is how things have worked out in practice.

Accepted Answer

You seem to be mixing up Team ID and code signing identifier. A Team ID is a short alphanumeric string allocated by Apple. For example, the one for my individual test team is SKMME9E2Y8. You can trust these, in this sense that you can be sure that:

  • Once Apple has issued a Team ID to a team, we won’t issue that same Team ID to any other team.

  • Only appropriately authorised members of that team can ship code signed with that Team ID [1].

In contrast, a code signing identifier is a way to uniquely identify code within a team [2]. It’s assigned by the team however they want. It’s traditional for bundled code to use the bundle ID as the code signing identifier. For example, a test app from DTS might have a bundle ID of com.example.apple-samplecode.Test727901 and have that same value as its code signing identifier. However, that’s not required. It’s common for you to encounter all sorts of weird values here, especially for code that’s not in a bundle.

Note In Creating Distribution-Signed Code for Mac I offer specific advice on how to set this for non-bundled code (search the doc for pig-jato to find it) but there’s absolutely no requirement for folks to follow that advice.

Apple generally identifies code using its designated requirement. For third-party code this typically includes both the Team ID and the code signing identifier. See TN3127 Inside Code Signing: Requirements for all the details.

Oh, and all of the above is about the Mac, and specifically Developer ID signed code on the Mac. If the code ships via an App Store, Apple applies further checks.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Modulo security breaches, of course |-:

[2] In theory this is more subtle but this is how things have worked out in practice.

I was hoping there was an easy way for a user to determine

  • UBF8T346G9 = Microsoft
  • EQHXZ8M8AV = Google
  • etc.

A lot of the time the first two components in the signing ID was helpful (e.g., com.google), but as Eskimo mentions, this is only a convention and not reliable as an unique identifier.

In the attached screenshot, I've searched for "crashpad". In the list of programs recently executed, and two different programs named "chrome_crashpad_handler" with the same signing ID ("chrome_crashpad_handler") popped up. Each had a different path. One was launched by Google Chrome (and had the Google Team ID) and one was launched by Microsoft Teams (and had the Microsoft Team ID).

My end goal is to identify every organization that contributed signed code that ran on a given machine. The Team ID seems to do it, but it isn't very understandable to humans.

My end goal is to identify every organization that contributed signed code that ran on a given machine.

You can get this info from the code signature of the executable:

  1. The ES client starts with an audit token.

  2. It maps that to a code object (SecCode).

  3. It calls SecCodeCopySigningInformation with kSecCodeInfoTrust to get a trust object (SecTrust).

  4. It calls SecTrustCopyCertificateChain to get the chain of trust, looking at the first item to get the certificate object (SecCertificate) of the signer.

  5. It calls SecCertificateCopySubjectSummary to easily get a string representation, or SecCertificateCopyData to get a ASN.1 DER representation that you can parse.

This is going to be slow, so the idea would be to cache the result based on the Team ID.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

trusting the team_id codesign naming scheme?
 
 
Q