Get started
SDK authentication quickstart

Signing a JWT in Swift / iOS

Sign a short-lived Sapling SDK credential in Swift / iOS without exposing your private API key to browser code.

SIGN Swift / iOS logo Swift / iOS HS256 · sub + exp

Swift / iOS JWT generator quickstart

Create a token with your public API key in the sub claim, a near-term Unix timestamp in exp, and an HS256 signature made with your private API key.

Sapling JWTs use HS256 with a sub claim containing your public API key and an exp claim containing a Unix timestamp. The examples use a one-hour lifetime; shorten it further when your application can refresh tokens easily.
Swift / iOS HS256 · sub + exp

This example uses JWTKit 5 with Swift 6 or newer.

import Foundation
import JWTKit

struct SaplingClaims: JWTPayload {
  let sub: SubjectClaim
  let exp: ExpirationClaim

  func verify(using algorithm: some JWTAlgorithm) async throws {
    try exp.verifyNotExpired()
  }
}

@main
struct Main {
  static func main() async throws {
    guard let publicKey = ProcessInfo.processInfo.environment["SAPLING_PUBLIC_KEY"],
          let privateKey = ProcessInfo.processInfo.environment["SAPLING_PRIVATE_KEY"] else {
      throw NSError(
        domain: "Quickstart",
        code: 1,
        userInfo: [
          NSLocalizedDescriptionKey:
            "Set SAPLING_PUBLIC_KEY and SAPLING_PRIVATE_KEY first."
        ]
      )
    }

    let keys = JWTKeyCollection()
    await keys.add(hmac: privateKey, digestAlgorithm: .sha256)
    let claims = SaplingClaims(
      sub: SubjectClaim(value: publicKey),
      exp: ExpirationClaim(value: Date().addingTimeInterval(3600))
    )

    print(try await keys.sign(claims))
  }
}
Generated token text/plain
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.<base64url-claims>.<signature>

Return the compact token to the browser and pass it to Sapling.init as the key. Issue a fresh token after it expires; never send the private key.

How a JWT is structured

A JSON Web Token (JWT) is a compact, URL-safe way to pass signed claims between two parties, most often for authentication. It has three base64url-encoded parts separated by dots: header.payload.signature.

Header
The token type (JWT) and the signing algorithm, such as HS256 (HMAC with SHA-256) or RS256 (RSA).
Payload
The claims: statements about the subject plus metadata such as an expiry. Claims are registered (standard names below), public, or private names agreed between the two parties.
Signature
The encoded header and payload signed with a secret (or private key) using the header's algorithm. It proves who issued the token and that it hasn't been changed in transit.

Standard JWT claims

Sapling checks only sub and exp, but these are the registered claims you will see in Swift / iOS JWT libraries:

  • iss (issuer): who issued the token.
  • sub (subject): who the token is about. For Sapling, your public API key.
  • aud (audience): the recipients the token is intended for.
  • exp (expiration time): seconds since the Unix epoch after which the token must be rejected.
  • nbf (not before): seconds since the epoch before which the token must be rejected.
  • iat (issued at): when the token was issued, in seconds since the epoch.
  • jti (JWT ID): a unique identifier that lets a server reject replayed tokens.

Use a vetted JWT library

Sign tokens with an established, maintained cryptography library rather than hand-rolling HMAC and base64url encoding. Those libraries are peer-reviewed, handle edge cases such as algorithm confusion and clock skew, and get patched when new vulnerabilities appear.

About Swift / iOS

Swift is a compiled programming language developed by Apple as a replacement for Objective-C. It is used with Cocoa and Cocoa Touch frameworks for application development for iOS and macOS platforms.