{"record":{"id":"c05498440835e1ee","repo":"git-ecosystem/git-credential-manager","slug":"errorsecinteractionnotallowed","errorCode":"ErrorSecInteractionNotAllowed","errorMessage":"Interaction with the Security Server is not allowed.","messagePattern":"Interaction with the Security Server is not allowed\\.","errorType":"error_code","errorClass":"InteropException","httpStatus":null,"severity":"error","filePath":"src/Core/Interop/MacOS/Native/SecurityFramework.cs","lineNumber":152,"sourceCode":"\n        public static void ThrowIfError(int error, string defaultErrorMessage = \"Unknown error.\")\n        {\n            switch (error)\n            {\n                case OK:\n                    return;\n                case ErrorSecNoSuchKeychain:\n                    throw new InteropException(\"The keychain does not exist.\", error);\n                case ErrorSecInvalidKeychain:\n                    throw new InteropException(\"The keychain is not valid.\", error);\n                case ErrorSecAuthFailed:\n                    throw new InteropException(\"Authorization/Authentication failed.\", error);\n                case ErrorSecDuplicateItem:\n                    throw new InteropException(\"The item already exists.\", error);\n                case ErrorSecItemNotFound:\n                    throw new InteropException(\"The item cannot be found.\", error);\n                case ErrorSecInteractionNotAllowed:\n                    throw new InteropException(\"Interaction with the Security Server is not allowed.\", error);\n                case ErrorSecInteractionRequired:\n                    throw new InteropException(\"User interaction is required.\", error);\n                case ErrorSecNoSuchAttr:\n                    throw new InteropException(\"The attribute does not exist.\", error);\n                default:\n                    throw new InteropException(defaultErrorMessage, error);\n            }\n        }\n    }\n\n    [Flags]\n    public enum SessionAttributeBits\n    {\n        SessionIsRoot = 0x0001,\n        SessionHasGraphicAccess = 0x0010,\n        SessionHasTty = 0x0020,\n        SessionIsRemote = 0x1000,\n    }","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Core/Interop/MacOS/Native/SecurityFramework.cs#L134-L170","documentation":"InteropException thrown by SecurityFramework.ThrowIfError when the macOS Security framework returns errSecInteractionNotAllowed (-25308). It means the requested keychain operation needed to talk to the Security Server (prompt the user, unlock the keychain) but the current session/process context forbids user interaction. The library cannot complete the operation without a UI, so it throws instead of hanging.","triggerScenarios":"Keychain reads (SecKeychainFindGenericPassword, SecItemCopyMatching) on a locked keychain from a process with no UI access: SSH session, launchd daemon, CI runner, or app running as another user; SecItemCopyMatching with kSecUseAuthenticationUIDisallow while the item requires user presence; background service attempting to access items whose ACL requires confirmation.","commonSituations":"CI/CD pipelines unlocking the login keychain non-interactively; macOS background daemons/agents started before login window; SSH remote builds touching keychain-backed settings; apps sandboxed or running as root where Security Server denies UI; Headless macOS VMs in test farms.","solutions":["Unlock the keychain non-interactively first: `security unlock-keychain -p <password> <keychain>` or SecKeychainUnlock with the password.","Run the process inside a logged-in GUI session (e.g. a LaunchAgent with LimitLoadToSessionType=Aqua) rather than a system daemon or SSH session.","Partition the keychain for CI (`security set-key-partition-list -S apple-tool:,apple: -k <password> <keychain>`) so items are readable without prompts.","For items requiring biometric/password auth (Touch ID / kSecAccessControl), drop that requirement or gate the operation on a UI-capable context.","Verify the process user matches the keychain owner; root or other users cannot be granted interactive access to a login keychain."],"exampleFix":"// before: CI daemon reads a locked login keychain and throws\nerr = SecKeychainFindGenericPassword(null, serviceLength, service, accountLength, account, out length, out data, IntPtr.Zero);\nSecurityFramework.ThrowIfError(err); // -25308, no UI available to unlock\n\n// after: pre-unlock the keychain non-interactively in CI setup\n// security unlock-keychain -p \"$KEYCHAIN_PASSWORD\" login.keychain\n// security set-key-partition-list -S apple-tool:,apple: -k \"$KEYCHAIN_PASSWORD\" login.keychain\nerr = SecKeychainFindGenericPassword(null, serviceLength, service, accountLength, account, out length, out data, IntPtr.Zero);\nSecurityFramework.ThrowIfError(err);","handlingStrategy":"retry","validationCode":"// Verify the process can access the keychain without UI before touching it\nvar (exitCode, _) = Run(\"security\", \"show-keychain-info login.keychain\");\nbool keychainAccessibleNonInteractively = exitCode == 0;\nif (!keychainAccessibleNonInteractively) throw new InvalidOperationException(\"Unlock the keychain before running: security unlock-keychain -p <pwd> login.keychain\");","typeGuard":"static bool IsSecInteractionNotAllowed(InteropException ex) => ex.ErrorCode == -25308; // errSecInteractionNotAllowed","tryCatchPattern":"try\n{\n    credential = ReadCredentialFromKeychain(service, account);\n}\ncatch (InteropException ex) when (ex.ErrorCode == -25308)\n{\n    // No UI available (SSH/daemon/CI): unlock non-interactively, then retry once.\n    UnlockKeychainNonInteractive(keychainPassword);\n    credential = ReadCredentialFromKeychain(service, account);\n}","preventionTips":["In CI, unlock the keychain in a before_script and set the partition list (`security set-key-partition-list -S apple-tool:,apple: -k <pwd>`).","Run background consumers as LaunchAgents in the Aqua session, not as root LaunchDaemons.","Avoid Touch ID / user-presence access-control flags for items read by headless services.","Detect headless/SSH contexts early and fail fast with a clear setup message instead of a raw interop error."],"tags":["macos","keychain","security-framework","headless","interop","ci"],"backgroundTag":"authentication-required","analyzedSha":"e8ce762cd04b4100ae637b5fbf39ef9d0a96561e","analyzedAt":"2026-09-11T17:15:08.753Z","contentChangedAt":"2026-09-11T17:15:08.753Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}