Skip to content

approov/approov-service-ios-webview

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Approov Service for iOS WebView

Swift Package Manager library for protecting selected WKWebView traffic with Approov on iOS.

The package injects a JavaScript bridge into the page, intercepts protected fetch, optional XMLHttpRequest, and form submissions, executes those requests through ApproovURLSession, and returns the response to the page. Requests outside the configured allowlist stay on the normal WebKit networking stack.

Important

Only endpoints declared in protectedEndpoints are proxied through native networking and protected by Approov.

Requirements

Item Value
Platform iOS 15+
Package manager Swift Package Manager
Library product ApproovServiceWebView

Installation

Xcode

  1. Open your app project in Xcode.
  2. Choose File -> Add Package Dependencies...
  3. Enter https://github.com/approov/approov-service-ios-webview.git
  4. Select the branch or version you want to pin.
  5. Add the ApproovServiceWebView product to your app target.

Package.swift

dependencies: [
    .package(
        url: "https://github.com/approov/approov-service-ios-webview.git",
        branch: "main"
    )
]

Then add the product dependency to your target:

.target(
    name: "MyApp",
    dependencies: [
        .product(
            name: "ApproovServiceWebView",
            package: "approov-service-ios-webview"
        )
    ]
)

Import the package in your app target:

import ApproovServiceWebView

What the Package Provides

Type Purpose
ApproovWebView SwiftUI host for a protected WKWebView.
ApproovWebViewController UIKit host for the same bridge and request pipeline.
ApproovWebViewFactory Low-level API for creating or installing an Approov bridge on a raw WKWebView.
ApproovWebViewConfiguration Main integration surface for Approov setup, endpoint allowlisting, optional XHR interception, token header settings, fail-open policy, and native request mutation.
ApproovWebViewProtectedEndpoint Scheme, host, path-prefix, and excluded-path-prefix matcher for protected traffic.
ApproovWebViewContent Initial content source for the web view: request, HTML string, or file URL.

ApproovServiceWebView re-exports the shared core types, so a single import ApproovServiceWebView is sufficient in app code.

Request Model

Protected requests follow this path:

  1. The package injects its bridge script at document start.
  2. Matching page requests are serialized from JavaScript and passed to native code.
  3. Native execution runs through ApproovURLSession, including your existing Approov mutator chain.
  4. The response is marshalled back into the page runtime.

Unmatched requests continue through WebKit unchanged.

Configuration

ApproovWebViewConfiguration is the main contract between the host app and the package.

Property Purpose
approovConfig Approov onboarding string for ApproovService.initialize(...).
protectedEndpoints Strict allowlist for traffic that should be routed through native networking.
approovTokenHeaderName Header name used for the Approov token. Default: approov-token.
approovTokenHeaderPrefix Optional header prefix, for example Bearer .
approovDevelopmentKey Optional development key applied after initialization.
allowRequestsWithoutApproovToken Controls fail-open vs fail-closed behavior when Approov cannot produce a token.
interceptXMLHttpRequests Enables or disables JavaScript XMLHttpRequest interception. Default: true.
configureApproovService Hook for one-time Approov setup beyond the default initialization path.
mutateRequest Native-only request mutation point for secrets or headers that must not be exposed to page JavaScript.
debugLoggingEnabled Enables opt-in debug OSLog output for the native bridge lifecycle.
bridgeHandlerName WebKit message handler name used by the injected bridge.

Quick Start

import ApproovServiceWebView
import SwiftUI

struct ProtectedWebExperience: View {
    private let configuration = ApproovWebViewConfiguration(
        approovConfig: "<your-approov-config>",
        protectedEndpoints: [
            ApproovWebViewProtectedEndpoint(
                host: "api.example.com",
                pathPrefix: "/v1/private"
            )
        ],
        debugLoggingEnabled: true,
        approovDevelopmentKey: "<your-development-key>",
        mutateRequest: { request in
            var request = request
            request.setValue("<api-key>", forHTTPHeaderField: "Api-Key")
            return request
        }
    )

    var body: some View {
        ApproovWebView(
            content: .request(
                URLRequest(url: URL(string: "https://app.example.com")!)
            ),
            configuration: configuration
        )
    }
}

UIKit Host

import ApproovServiceWebView

let controller = ApproovWebViewController(
    content: .request(URLRequest(url: URL(string: "https://app.example.com")!)),
    configuration: configuration
)

Raw WKWebView Integration

Use ApproovWebViewFactory when your app wants the protected WKWebView instance directly instead of going through the SwiftUI or UIKit host wrappers.

Create a Web View and Load Later

import ApproovServiceWebView
import WebKit

let configuration = ApproovWebViewConfiguration(
    approovConfig: "<your-approov-config>",
    protectedEndpoints: [
        ApproovWebViewProtectedEndpoint(
            host: "api.example.com",
            pathPrefix: "/v1/private"
        )
    ]
)

let webView = ApproovWebViewFactory.makeWebView(
    configuration: configuration
)

// Load content whenever your app is ready.
webView.load(
    URLRequest(url: URL(string: "https://app.example.com")!)
)

Install on an Existing Customized WKWebView

import ApproovServiceWebView
import WebKit

let baseConfiguration = WKWebViewConfiguration()
baseConfiguration.userContentController = WKUserContentController()
baseConfiguration.websiteDataStore = .nonPersistent()
baseConfiguration.defaultWebpagePreferences.allowsContentJavaScript = true

let webView = WKWebView(frame: .zero, configuration: baseConfiguration)
webView.scrollView.bounces = true
webView.backgroundColor = .clear

ApproovWebViewFactory.install(
    on: webView,
    configuration: configuration
)

webView.load(
    URLRequest(url: URL(string: "https://app.example.com")!)
)

Note

If you attach Approov to an existing WKWebView, do it before the first protected page load, or reload after installation. The bridge is injected at document start and cannot retrofit a page that already finished loading.

Debug Logging

Set debugLoggingEnabled: true in ApproovWebViewConfiguration to emit debug-level OSLog entries for:

  • bridge installation and reuse
  • request receipt and native routing
  • cookie synchronization boundaries
  • lazy Approov initialization
  • protected request execution and response handling

The debug logs intentionally avoid request bodies, cookie values, token values, and URL query strings.

Operational Notes

  • Use protectedEndpoints to keep the native interception scope explicit and reviewable.
  • Use excludedPathPrefixes when you want to protect an entire host or broad path while allowing static assets or other public subpaths to stay on the normal WebKit stack.
  • Set interceptXMLHttpRequests to false if the host web app depends on native WebKit XHR behavior and only needs Approov protection for fetch or forms.
  • Keep secrets, API keys, and tenant-specific headers inside mutateRequest, not in page JavaScript.
  • Use configureApproovService if your app needs one-time Approov setup beyond a development key.
  • For reused base web views, install the bridge before the first protected navigation, or reload after installation.
  • Keep bridgeHandlerName unique if your app already registers page-world WKScriptMessageHandlers on the same WKUserContentController.
  • Default behavior is fail-closed. Set allowRequestsWithoutApproovToken only when your use case explicitly requires fail-open handling.

Example:

ApproovWebViewProtectedEndpoint(
    host: "store.example.com",
    pathPrefix: "/",
    excludedPathPrefixes: [
        "/assets/static"
    ]
)

Related Dependencies

This package resolves and uses:

About

Swift Package Manager library for protecting selected WKWebView traffic with Approov on iOS.

Resources

License

Stars

Watchers

Forks

Contributors

Languages