{"id":15134836,"url":"https://github.com/jetbrains/apple-notary-api-kotlin-client","last_synced_at":"2025-10-19T14:32:50.104Z","repository":{"id":65982514,"uuid":"544909598","full_name":"JetBrains/apple-notary-api-kotlin-client","owner":"JetBrains","description":"Apple Notary API client for Kotlin","archived":false,"fork":false,"pushed_at":"2023-05-09T08:39:59.000Z","size":184,"stargazers_count":14,"open_issues_count":0,"forks_count":4,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-01-30T02:01:38.004Z","etag":null,"topics":["apple","kotlin"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JetBrains.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-03T12:56:20.000Z","updated_at":"2025-01-24T15:03:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"a98b3f5a-5843-4e1c-a057-8085032cb25f","html_url":"https://github.com/JetBrains/apple-notary-api-kotlin-client","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JetBrains%2Fapple-notary-api-kotlin-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JetBrains%2Fapple-notary-api-kotlin-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JetBrains%2Fapple-notary-api-kotlin-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JetBrains%2Fapple-notary-api-kotlin-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JetBrains","download_url":"https://codeload.github.com/JetBrains/apple-notary-api-kotlin-client/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237152875,"owners_count":19263796,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apple","kotlin"],"created_at":"2024-09-26T05:40:16.191Z","updated_at":"2025-10-19T14:32:44.796Z","avatar_url":"https://github.com/JetBrains.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# apple-notary-api-kotlin-client\n\n[![JetBrains team project](http://jb.gg/badges/team.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)\n[![Github Build](https://github.com/JetBrains/apple-notary-api-kotlin-client/actions/workflows/build.yml/badge.svg)](https://github.com/JetBrains/apple-notary-api-kotlin-client/actions/workflows/build.yml)\n[![GitHub license](https://img.shields.io/badge/license-APACHE_2.0-blue.svg)](https://github.com/JetBrains/apple-notary-api-kotlin-client/blob/main/LICENSE)\n\n[Apple Notary API](https://developer.apple.com/documentation/notaryapi) client for [Kotlin](https://kotlinlang.org).\n\nNotarize your macOS application from Kotlin code without dependency on [Xcode](https://developer.apple.com/xcode) nor [macOS](https://www.apple.com/macos).\n\n## Add the dependency\n\nThis library is available on Space Packages, you will need to add this Maven repository to your Gradle configuration:\n\n```kotlin\nimport java.net.URI\n\nrepositories {\n    maven {\n        url = URI(\"https://packages.jetbrains.team/maven/p/ij/intellij-dependencies\")\n    }\n}\n```\n\nThen add the dependency\n\n```kotlin\nimplementation(\"org.jetbrains:apple-notary-api-kotlin-client:$version\")\n```\n\nYou will also need to provide a Ktor engine implementation, for example if you want to use the CIO engine:\n\n```kotlin\nimplementation(\"io.ktor:ktor-client-cio:$ktorVersion\")\n```\n\n## Usage\n\nYou will first need to create an API Key for App Store Connect API,\nsee [Apple's Documentation](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api)\n.\nWhile doing this process make sure to save:\n\n- your issuer ID from the API Keys page in App Store Connect (e.g. `57246542-96fe-1a63-e053-0824d011072a`)\n- your private key ID from App Store Connect (e.g. `2X9R4HXF34`)\n- your private key `.p8` file you can download from the API Keys page in App Store Connect\n\nOnce you have these information, you can setup a credential object:\n\n```kotlin\nimport com.jetbrains.notary.NotaryClientV2\nimport com.jetbrains.notary.auth.AppStoreConnectAPIKey\n\nval credentials = AppStoreConnectAPIKey(\n    issuerId = \"your-issuer-id\",\n    keyId = \"your-private-key-id\",\n    privateKey = \"your-private-key-file-content\",\n)\n\nval client = NotaryClientV2(credentials)\n\n// ... now you can use your client!\n\n// For example retrieving your previous submissions:\nval submissions = client.getPreviousSubmissions()\nprintln(submissions)\n```\n\n### Extensions\n\n`apple-notary-api-kotlin-client` provides some extension functions that cover basic use cases of \n[Apple Notary API](https://developer.apple.com/documentation/notaryapi).\n\n#### Functions `notarize` or `notarizeBlocking`\n\n`notarize` (or its blocking equivalent `notarizeBlocking`) will cover the basic use case of \"I want to notarize a file,\nwait for the notarization to complete, get status and logs of the submission result when completed\".\nUnder the hood, it will do the following:\n- Issue a notarization submission for the specified file\n- Upload the specified file to the location asked by [Apple Notary API](https://developer.apple.com/documentation/notaryapi)\n- Poll [Apple Notary API](https://developer.apple.com/documentation/notaryapi) until the submission completes (or timeout)\n  - _Note: with configuration such as `ignoreServerError` and `ignoreTimeoutExceptions` set to `true` (set by default), polling will be hardened not to fail on usual false negative situations_\n- Fetch logs of the completed submission (whether it is a success or a failure)\n- Return status and logs of the completed submission\n\n##### Example usage snippet\n\n```kotlin\nimport com.jetbrains.notary.NotaryClientV2\nimport com.jetbrains.notary.auth.AppStoreConnectAPIKey\nimport kotlin.time.Duration.Companion.minutes\n\nval credentials = AppStoreConnectAPIKey(\n    issuerId = \"your-issuer-id\",\n    keyId = \"your-private-key-id\",\n    privateKey = \"your-private-key-file-content\",\n)\n\nval notaryApiClient = NotaryClientV2(credentials)\nval notarizationResult = notaryApiClient.notarizeBlocking(file, StatusPollingConfiguration(\n    timeout = 30.minutes,\n    pollingPeriod = 1.minutes,\n    ignoreServerError = true,\n    ignoreTimeoutExceptions = true,\n))\n\nval json = Json { prettyPrint = true }\nprintln(\"Notarization logs:\\n${json.encodeToString(notarizationResult.logs)}\")\n\nwhen (notarizationResult.status) {\n    SubmissionResponse.Status.ACCEPTED -\u003e println(\"Notarization of $file successful\")\n    SubmissionResponse.Status.IN_PROGRESS, null -\u003e error(\"Timed out polling status of $file notarization submission\")\n    SubmissionResponse.Status.INVALID, SubmissionResponse.Status.REJECTED -\u003e error(\"Notarization of $file failed, see logs above\")\n}\n```\n\n### Configuration\n\n#### Use your own `ktor` client implementation\n\nYou are free to use your own `ktor` client implementation and thus configuration.\nWe provide `NotaryClientV2.defaultHttpClient` to allow your client configuration to extend the default one.\n\n##### Example of configuration: change retry policy\n\n```kotlin\nimport com.jetbrains.notary.NotaryClientV2\nimport com.jetbrains.notary.auth.AppStoreConnectAPIKey\nimport kotlin.time.Duration.Companion.minutes\n\nval credentials = AppStoreConnectAPIKey(\n  issuerId = \"your-issuer-id\",\n  keyId = \"your-private-key-id\",\n  privateKey = \"your-private-key-file-content\",\n)\n\nval myOwnClient = NotaryClientV2.defaultHttpClient.config { // keep all the default configuration\n  install(HttpRequestRetry) {\n    retryOnExceptionOrServerErrors(maxRetries = 10) // but increase the number of retry of the default configuration\n    constantDelay(millis = 1.minutes.inWholeMilliseconds) // but change the default exponential retry by a constant one\n  }\n}\n\nval notaryApiClient = NotaryClientV2(credentials, httpClient = myOwnClient)\n```\n\n## License\n\nThis project is distributed under the Apache 2.0 license.\n\n## Acknowledgment\n\nSpecial thanks to the people that built Rust library\n[apple-codesign](https://github.com/indygreg/apple-platform-rs/tree/main/apple-codesign) that inspired this work.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjetbrains%2Fapple-notary-api-kotlin-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjetbrains%2Fapple-notary-api-kotlin-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjetbrains%2Fapple-notary-api-kotlin-client/lists"}