Securing 2M+ accounts & $15B+ in assets, protected & secure·B5 Secure™ — per data-element authorization for .NET platforms

Secure an Apple iOS App

Native client

Secure an Apple iOS App

An iOS app must never contain a tenant-wide signing secret. Use user-bound OAuth with PKCE, Keychain or Secure Enclave-backed key material, short-lived tokens, device registration, and server-side policy.

Integration path

Required controls

Implementation steps

Register exact bundle, team, redirect, and universal-link identifiers.
Use authorization code with PKCE and short-lived access tokens.
Store refresh material only in the approved secure storage class.
Generate a device key and register its public key with the B5 customer environment.
Send device proof and attestation to the backend; never make the mobile app the final policy authority.
Test device reset, token theft, attestation failure, offline behavior, and revocation.

Control details

Pkce

Generate a high-entropy verifier per authorization attempt and validate the code challenge at the authorization service.

Storage

Use Keychain access controls appropriate to the risk. Avoid synchronizable storage for enterprise credentials unless explicitly approved.

Device Proof

Use a device-held private key to prove possession without exporting key material.

Attest

Validate App Attest assertions on the server, bind them to the application and request context, and define fallback and denial policy.

Apple iOS

PKCE plus a device-held key, never an embedded tenant secret

Swift PKCE excerpt
import AuthenticationServices
import CryptoKit
import Foundation
import Security

struct B5PKCE {
    static func verifier() -> String {
        var bytes = [UInt8](repeating: 0, count: 32)
        precondition(SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes) == errSecSuccess)
        return Data(bytes).base64URLEncodedString()
    }

    static func challenge(for verifier: String) -> String {
        let digest = SHA256.hash(data: Data(verifier.utf8))
        return Data(digest).base64URLEncodedString()
    }
}

extension Data {
    func base64URLEncodedString() -> String {
        base64EncodedString()
            .replacingOccurrences(of: "+", with: "-")
            .replacingOccurrences(of: "/", with: "_")
            .replacingOccurrences(of: "=", with: "")
    }
}

// Register the app's bundle ID, team ID, exact callback URL, and public device key.
// Keep refresh material in Keychain. Never embed a tenant-wide B5 signing secret.
  • Register the exact bundle ID, team ID, callback, and universal-link identities.
  • Use authorization code with PKCE and short-lived access tokens.
  • Keep refresh material in the approved Keychain access class.
  • Register a device public key and verify proof server-side.
  • Use App Attest as a server-verified signal, not as identity by itself.
Developer Relations

Talk to a human.

Get architecture guidance, Test Mode access, integration review, or help choosing the right B5 identity and authorization pattern.

Scroll to Top