The same project signs in a graphical macOS session but fails over SSH with errSecInternalComponent.
Fastest fix: Check which macOS account and session run the build, whether its login Keychain is unlocked, and whether codesign can use the signing identity. Don’t rebuild certificates first; errSecInternalComponent can have more than one cause, so use the evidence to choose the next check. Apple Developer Technical Support discusses this error in SSH and CI contexts and identifies a locked Keychain as one possible cause in its code-signing troubleshooting discussions.
This guide is for indie developers who run xcodebuild archive over SSH on a remote Mac and encounter a CodeSign error.
It also helps small teams check whether a self-hosted build task uses the same account and environment as an interactive login.
If the signing identity is present but remote signing still fails, use the checks below to separate Keychain access from certificate or profile issues.
00Locate the first signing failure
Start with the first relevant error in the build log, not the last line printed by the shell. A build may fail while compiling, while signing a target, or after signing during export or upload. Those failures need different fixes.
Search the full log for CodeSign, codesign, and the first occurrence of errSecInternalComponent. Note the target name and the action that failed. If the log shows compiler errors before any CodeSign step, this is not yet a signing problem. If an Archive completes but an upload later fails, investigate the upload stage rather than changing signing credentials.
Check the Xcode installation that the SSH task actually uses. A shell can find a different developer directory from the one selected in the graphical session. Record the output of:
xcodebuild -version
xcode-select -p
Compare those results with the Xcode installation used for the successful graphical build. For behavior specific to this release, check Apple’s Xcode 27 release notes; don’t assume that a result from a different Xcode build proves a general Xcode 27 defect.
Next, compare the same project and scheme in both environments. Keep the workspace, scheme, signing settings, and source revision unchanged. The comparison only helps if the inputs stay fixed: otherwise a changed scheme or profile can look like a session-related failure.
Keep the first failure intact. Save the relevant, redacted log before changing Keychain state, credentials, or project settings. A later successful run may hide the condition that caused the original failure.
01Check the account and session that run the task
A successful SSH login does not prove that a scheduled job, CI runner, or wrapper script runs as that same account. A task can inherit a different user, home directory, or launch context. That matters because a signing identity stored in one user’s Keychain may not be available to a process running under another account.
How can the SSH task’s macOS user be confirmed?
Run these checks in the same shell or task that launches the build:
id -un
printf '%s\n' "$HOME"
Then inspect the task definition and any wrapper scripts for a user switch, sudo, a service manager, or a CI setting that changes the execution account. Compare the task’s username and home directory with those from the working graphical session. Do not treat a successful xcodebuild command as proof that the two environments share the same security context.
Apple’s technical note on Daemons and Agents and their execution contexts explains why background processes and interactive user sessions should be treated separately. Apply that distinction to the build setup: an SSH shell, a scheduled task, and a graphical login may have different access to user-scoped resources even when they run on the same Mac.
If the account or home directory differs, correct the task configuration or deliberately install and authorize signing assets for the account that should run the build. Don’t copy private credentials between accounts as a quick workaround.
Why can SSH xcodebuild return errSecInternalComponent?
SSH runs without the same interactive desktop experience as a graphical login. A prompt that would appear during a local session may not be available to an unattended command. Apple DTS lists SSH and CI among the environments where this error can arise and describes a locked Keychain as one possible explanation. The error alone does not identify the cause.
This distinction helps avoid a common detour: changing certificates because the error mentions signing, even though the signing identity is valid and the failure occurs because the process cannot access it. The diagnostic target is the exact context used by the failing task—not simply whether a person can sign the app from the desktop.
02Verify Keychain availability before changing assets
Identify the user Keychain that contains the signing identity and check its state while the task runs. The relevant question is not only whether the Keychain is unlocked in a desktop session, but whether it is usable by the SSH process at the moment codesign requests the identity.
What if the login Keychain is unlocked but codesign still fails?
Treat “unlocked” as one condition, not proof that the whole signing path works. Check the following in the same execution context as the failed Archive:
- The task runs under the account that owns or can access the intended Keychain.
- The expected Keychain is in that account’s search list.
- The Keychain is available when the build begins, rather than only after a graphical login prompt.
- The signing identity appears to the task, not just to a separate interactive shell.
- The task has permission to use the identity’s private key.
Apple’s documentation on storing a signing identity in the Keychain describes the identity as a certificate associated with its private key. If the certificate is visible but the private key is missing or inaccessible, the identity may still be unusable for signing.
Avoid putting a Keychain password in a repository, a command-line argument, a shared build log, or a script committed with the project. A prompt that cannot be answered in an SSH session is not a reason to expose a password in plaintext. Use an access-controlled method for provisioning and unlocking credentials, restrict who can read it, and keep diagnostic logs free of secrets.
Don’t apply a broad permission change as a universal fix. Keychain access depends on the account, Keychain, identity, and task context. A permission adjustment that helps one setup may be irrelevant—or weaken protection—in another.
03Check the identity and project signing assets separately
Once the task can access the intended Keychain, inspect the signing identity and project configuration. Keep these checks separate: a missing private key is not the same problem as an invalid certificate, and neither proves that a provisioning profile matches the app.
Does the identity include a usable private key?
Confirm that the identity expected by the project is present for the task’s account, and that its matching private key is available. If the Keychain is accessible but signing still fails, examine the evidence for an incomplete identity, duplicate identities, or a certificate-chain problem before changing project settings.
Apple’s certificate overview explains certificate types and protection considerations. Apple’s iOS code-signing troubleshooting note is also a useful reference when the failure points to code signing itself. Neither source makes a single access-control setting appropriate for every remote build. Verify what the task can actually use before changing permissions.
If a diagnostic command reports multiple identities, don’t guess which one Xcode selected. Match the identity to the project’s configured team and signing settings, then confirm the build log shows that intended identity. Redact certificate identifiers and team details before sharing logs outside the team.
When should certificate and profile matching be investigated?
Move to certificate and profile checks when the error evidence points there: for example, the selected identity is absent or invalid, the app’s bundle identifier does not match the profile, or the expected team is not associated with the signing configuration. Check that the profile is intended for the build’s signing method and app identifier.
Apple’s guidance for editing, downloading, or deleting provisioning profiles covers profile maintenance. For a built app, Apple also documents how to inspect and diagnose entitlements. Use those checks when the logs or the Archive point to a profile or entitlement mismatch—not as a substitute for resolving a non-interactive Keychain problem.
Don’t revoke and recreate certificates simply because SSH signing failed. That can disrupt other release machines while leaving the actual cause, such as a different task account or unavailable Keychain, untouched.
04Choose the next check from the evidence
Use these branches to decide what to investigate next:
- If the same project signs in the GUI but fails over SSH: compare the task account, home directory, Keychain state, and identity access before changing certificates.
- If the SSH task runs as a different account: correct the runner configuration or provision the required identity for the intended account through a controlled process.
- If the identity is visible but its private key is absent or inaccessible: repair the identity or its authorized access; don’t start by replacing the provisioning profile.
- If the signing identity is usable but the log reports a team, bundle identifier, profile, or entitlement mismatch: investigate project signing settings and profile selection.
- If compilation fails before CodeSign: fix the compile or dependency issue first; signing changes won’t address it.
- If the Archive succeeds and only upload fails: preserve the successful Archive and investigate the upload credentials or transport stage separately.
| Evidence from the failed run | Likely layer to inspect next | Avoid doing first |
|---|---|---|
| GUI signing works; SSH signing fails | Task account, session, Keychain access | Recreating certificates |
| Identity is listed but signing cannot use its private key | Private-key availability and authorization | Replacing the provisioning profile |
| Log points to a team, bundle identifier, profile, or entitlement | Project signing settings and profile match | Changing SSH account settings without evidence |
| Build fails before a CodeSign action | Compile, dependency, or build configuration | Changing Keychain permissions |
| Archive succeeds but upload fails | Upload credentials and upload stage | Rebuilding the signing identity |
05Validate the fix with a real Archive
A passing identity lookup is not the final acceptance test. Re-run an Archive under the same account, SSH entry point, and task configuration that failed. Use the project’s actual workspace and scheme, and keep paths as local placeholders:
xcodebuild \
-workspace "<WORKSPACE>.xcworkspace" \
-scheme "<SCHEME>" \
-destination "generic/platform=iOS" \
-archivePath "<ARCHIVE_PATH>" \
archive
Check the complete command result and the first CodeSign-related entries in the resulting log. Confirm that the Archive was created, that the intended signing identity was used, and that the app’s signature and entitlements match the release configuration. If a later export or upload step is part of the production task, validate that stage separately; a successful Archive does not establish that upload credentials or delivery settings work.
| Acceptance check | Pass condition | If it fails |
|---|---|---|
| Execution context | The Archive runs as the intended account with the expected home directory | Correct the runner or task configuration |
| Keychain access | The task can use the intended identity without a GUI prompt | Recheck Keychain availability and private-key access |
| Archive result | The expected Archive is produced and CodeSign completes | Return to the first failing log entry |
| Signing assets | Identity, team, app identifier, profile, and entitlements agree | Fix only the mismatched signing layer |
| Credential handling | Logs and scripts contain no exposed passwords or tokens | Remove secrets, rotate exposed credentials, and restrict access |
Record the Xcode version, macOS version, task account, Keychain location, and the stage where failure occurred. Redact host addresses, tokens, certificate identifiers, team IDs, bundle identifiers, and sensitive paths before sharing the record. This makes the next failure comparable without turning a diagnostic log into a credential leak.
For a remote build workflow, the meaningful acceptance condition is not “the command ran once.” It is that a release Archive succeeds through the same non-interactive path used by the real task, with the expected signing assets and no dependency on an unavailable desktop prompt.
06Decide whether to keep the current Mac setup
A self-managed Mac can make sense when the team already owns suitable hardware, needs local peripherals, or runs a steady workload that justifies maintaining a dedicated machine. Its trade-offs include upfront hardware cost, responsibility for macOS and Xcode maintenance, and the need to manage power, storage, backups, and remote access.
A remote Mac can be a better fit when the blocker is access to a maintained macOS build environment rather than a need to own the hardware. Renting avoids buying a Mac solely for occasional or release-driven signing work, but it does not remove the need to secure credentials or verify the task’s account and Keychain setup. Teams with continuous heavy workloads should compare ongoing rental costs with ownership; teams that need physical devices or direct hardware connections may be better served by a local Mac.
If the signing assets and project configuration are already correct and the remaining issue is the remote execution environment, review NUKCLOUD’s Mac access options and compare them with the team’s SSH workflow. For temporary release work or a test environment, NUKCLOUD Mac rental plans offer a way to validate that workflow without first purchasing a dedicated build Mac.