{"id":40970657,"url":"https://github.com/coenttb/swift-jwt","last_synced_at":"2026-01-22T06:43:07.342Z","repository":{"id":306885169,"uuid":"1027566075","full_name":"coenttb/swift-jwt","owner":"coenttb","description":"A Swift package for creating, signing, and verifying JSON Web Tokens.","archived":false,"fork":false,"pushed_at":"2025-10-30T20:52:19.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-30T22:26:34.725Z","etag":null,"topics":["crypto","jwt","jwt-signer","jwt-token","jwt-verifier","swift"],"latest_commit_sha":null,"homepage":"https://coenttb.com","language":"Swift","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/coenttb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-28T07:50:13.000Z","updated_at":"2025-10-30T20:50:16.000Z","dependencies_parsed_at":"2025-07-28T08:51:29.717Z","dependency_job_id":"6f3fb7c2-fa76-4605-853d-9a80a09ca21c","html_url":"https://github.com/coenttb/swift-jwt","commit_stats":null,"previous_names":["coenttb/swift-jwt"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/coenttb/swift-jwt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coenttb%2Fswift-jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coenttb%2Fswift-jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coenttb%2Fswift-jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coenttb%2Fswift-jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coenttb","download_url":"https://codeload.github.com/coenttb/swift-jwt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coenttb%2Fswift-jwt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28657110,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["crypto","jwt","jwt-signer","jwt-token","jwt-verifier","swift"],"created_at":"2026-01-22T06:43:06.834Z","updated_at":"2026-01-22T06:43:07.332Z","avatar_url":"https://github.com/coenttb.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# swift-jwt\n\n[![CI](https://github.com/coenttb/swift-jwt/workflows/CI/badge.svg)](https://github.com/coenttb/swift-jwt/actions/workflows/ci.yml)\n![Development Status](https://img.shields.io/badge/status-active--development-blue.svg)\n\nA Swift package for creating, signing, and verifying JSON Web Tokens (JWTs) using Apple's Crypto framework.\n\n## Features\n\n- HMAC-SHA256/384/512 and ECDSA-SHA256 signing algorithms\n- RFC 7519 compliant JWT implementation via `swift-rfc-7519`\n- Apple Crypto framework integration via `swift-crypto`\n- Static methods for HMAC and ECDSA JWT creation\n- JWT header, claims, and timing configuration\n- Type-safe JWT handling via Swift's type system\n- Signature verification with timing validation (exp, nbf, iat)\n\n## Requirements\n\n- **Platforms**: macOS 13.0+, iOS 16.0+\n- **Swift**: 5.9+ (Swift 6.0 supported)\n\n## Installation\n\nAdd this package to your `Package.swift`:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/coenttb/swift-jwt.git\", from: \"0.1.0\")\n]\n```\n\n## Quick Start\n\n### Creating JWTs\n\n#### HMAC-SHA256 (Recommended for shared secrets)\n\n```swift\nimport JWT\n\n// Create a JWT with HMAC-SHA256\nlet jwt = try JWT.hmacSHA256(\n    issuer: \"example.com\",\n    subject: \"user123\",\n    audience: \"api.example.com\",\n    expiresIn: 3600, // 1 hour\n    claims: [\"role\": \"admin\", \"permissions\": [\"read\", \"write\"]],\n    secretKey: \"your-secret-key\"\n)\n\n// Get the token string\nlet tokenString = try jwt.compactSerialization()\n```\n\n#### ECDSA-SHA256 (Recommended for public/private key pairs)\n\n```swift\nimport JWT\nimport Crypto\n\n// Generate or load your ECDSA private key\nlet privateKey = P256.Signing.PrivateKey()\n\nlet jwt = try JWT.ecdsaSHA256(\n    issuer: \"secure-service\",\n    subject: \"user456\",\n    audience: \"mobile-app\",\n    expiresIn: 7200, // 2 hours\n    claims: [\"scope\": \"user:read\"],\n    privateKey: privateKey\n)\n```\n\n### Verifying JWTs\n\n#### HMAC Verification\n\n```swift\nimport JWT\n\n// Parse JWT from token string\nlet jwt = try JWT.parse(from: tokenString)\n\n// Create verification key\nlet verificationKey = VerificationKey.symmetric(string: \"your-secret-key\")\n\n// Verify signature only\nlet isValidSignature = try jwt.verify(with: verificationKey)\n\n// Verify signature and validate timing (exp, nbf, iat)\nlet isFullyValid = try jwt.verifyAndValidate(with: verificationKey)\n```\n\n#### ECDSA Verification\n\n```swift\nimport JWT\nimport Crypto\n\n// Create verification key from signing key\nlet privateKey = P256.Signing.PrivateKey()\nlet verificationKey = VerificationKey.ecdsa(from: .ecdsa(privateKey))!\n\n// Verify the JWT\nlet isValid = try jwt.verifyAndValidate(with: verificationKey)\n```\n\nAlternative - using raw public key data:\n\n```swift\nimport JWT\nimport Crypto\n\nlet privateKey = P256.Signing.PrivateKey()\nlet publicKeyData = privateKey.publicKey.rawRepresentation\nlet verificationKey = try VerificationKey.ecdsa(rawRepresentation: publicKeyData)\n\nlet isValid = try jwt.verifyAndValidate(with: verificationKey)\n```\n\n## Advanced Usage\n\n### Custom JWT Configuration\n\n```swift\nimport JWT\n\nlet jwt = try JWT.signed(\n    algorithm: .hmacSHA384,\n    key: .symmetric(string: \"custom-key\"),\n    issuer: \"custom-issuer\",\n    subject: \"user789\",\n    audiences: [\"api1.example.com\", \"api2.example.com\"], // Multiple audiences\n    expiresAt: Date(timeIntervalSinceNow: 86400), // Custom expiration\n    notBefore: Date(timeIntervalSinceNow: 300), // Valid in 5 minutes\n    jti: UUID().uuidString, // JWT ID\n    claims: [\n        \"role\": \"moderator\",\n        \"permissions\": [\"read\", \"moderate\"],\n        \"active\": true\n    ],\n    headerParameters: [\n        \"kid\": \"key-identifier\",\n        \"custom\": \"header-value\"\n    ]\n)\n```\n\n### Working with Claims\n\n```swift\n// Access standard claims\nprint(\"Issuer: \\(jwt.payload.iss ?? \"Unknown\")\")\nprint(\"Subject: \\(jwt.payload.sub ?? \"Unknown\")\")\nprint(\"Expires: \\(jwt.payload.exp?.description ?? \"Never\")\")\n\n// Access custom claims\nlet role = jwt.payload.additionalClaim(\"role\", as: String.self)\nlet permissions = jwt.payload.additionalClaim(\"permissions\", as: [String].self)\nlet isActive = jwt.payload.additionalClaim(\"active\", as: Bool.self)\n```\n\n### Timing Validation\n\n```swift\n// Validate with custom timing parameters\nlet isValid = try jwt.verifyAndValidate(\n    with: verificationKey,\n    currentTime: Date(), // Custom current time\n    clockSkew: 120 // Allow 2 minutes clock skew\n)\n```\n\n### Key Management\n\n```swift\n// Symmetric keys\nlet stringKey = SigningKey.symmetric(string: \"secret\")\nlet dataKey = SigningKey.symmetric(data: keyData)\n\n// ECDSA keys\nlet generatedKey = SigningKey.generateECDSA()\nlet existingKey = try SigningKey.ecdsa(rawRepresentation: privateKeyData)\n\n// Verification keys\nlet symmetricVerify = VerificationKey.symmetric(string: \"secret\")\nlet ecdsaVerify = VerificationKey.ecdsa(from: signingKey)\nlet publicKeyVerify = try VerificationKey.ecdsa(rawRepresentation: publicKeyData)\n```\n\n## Supported Algorithms\n\n| Algorithm | Description | Use Case |\n|-----------|-------------|----------|\n| `HS256` | HMAC-SHA256 | Shared secret scenarios |\n| `HS384` | HMAC-SHA384 | Enhanced security with shared secrets |\n| `HS512` | HMAC-SHA512 | Maximum security with shared secrets |\n| `ES256` | ECDSA-SHA256 | Public/private key scenarios |\n| `none` | No signature | Testing only (not recommended for production) |\n\n## Error Handling\n\nThe package throws RFC 7519 compliant errors:\n\n```swift\ndo {\n    let jwt = try JWT.hmacSHA256(/*...*/)\n    let isValid = try jwt.verifyAndValidate(with: key)\n} catch RFC_7519.Error.invalidSignature(let message) {\n    print(\"Invalid signature: \\(message)\")\n} catch RFC_7519.Error.tokenExpired {\n    print(\"Token has expired\")\n} catch RFC_7519.Error.tokenNotYetValid {\n    print(\"Token not yet valid\")\n} catch {\n    print(\"Other error: \\(error)\")\n}\n```\n\n## Dependencies\n\nThis package is built on top of:\n\n- [swift-rfc-7519](https://github.com/swift-web-standards/swift-rfc-7519) - RFC 7519 compliant JWT implementation\n- [swift-crypto](https://github.com/apple/swift-crypto) - Apple's cryptographic framework\n\n## Security Considerations\n\n- **Key Management**: Store secret keys securely and rotate them regularly\n- **Algorithm Choice**: Use ECDSA for distributed systems, HMAC for simple scenarios\n- **Token Expiration**: Always set appropriate expiration times\n- **Timing Validation**: Enable timing validation in production\n- **HTTPS Only**: Always transmit JWTs over HTTPS\n- **Never Log Tokens**: Avoid logging JWTs in production systems\n\n## Testing\n\nRun the test suite:\n\n```bash\nswift test\n```\n\nThe package includes comprehensive tests covering:\n- JWT creation with all supported algorithms\n- Signature verification\n- Timing validation\n- Edge cases and error conditions\n- Key management operations\n\n## Related Packages\n\n### Used By\n\n- [swift-identities-types](https://github.com/coenttb/swift-identities-types): A Swift package with foundational types for authentication.\n- [swift-server-foundation](https://github.com/coenttb/swift-server-foundation): A Swift package with tools to simplify server development.\n- [swift-web-foundation](https://github.com/coenttb/swift-web-foundation): A Swift package with tools to simplify web development.\n\n### Third-Party Dependencies\n\n- [apple/swift-crypto](https://github.com/apple/swift-crypto): Open-source implementation of a substantial portion of the API of Apple CryptoKit.\n\n## Contributing\n\nContributions are welcome. Please open an issue or submit a pull request.\n\n## License\n\nThis project is licensed under the **Apache 2.0 License**. See the [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoenttb%2Fswift-jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoenttb%2Fswift-jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoenttb%2Fswift-jwt/lists"}