1

My team and I are beginning to mock our API responses in our iOS app so we don't have to worry about our backend being up when testing.

I have conditional compilation directives based on the SWIFT_ACTIVE_COMPILATION_CONDITIONS flag, specifically DEBUG MOCK_SYSTEM. This flag controls whether my code uses mock data or sends real network requests. While it works, I'm concerned about the security of exposing confidential non-production API keys in the development and testing process.

#if MOCK_SYSTEM
        DispatchQueue.main.asyncAfter(deadline: .now() + mockRequestDelay) {
            completion(.success(MOCK.accountCreateResponse))
        }
#else
        sendWLRequest(
            request: .postAccountCreate,
            body: account.toBodyString(),
            firebaseAnalyticsCategory: .enrollmentApiError,
            additionalRequestSettings: { request in
                request.timeoutInterval = NetworkService.Timeout.enrollment.value
                request.setJsonAsContentType()
            },
            completion: internalCompletion
        )
#endif

I'm using #if MOCK_SYSTEM to conditionally execute code for mock responses or real network requests. The code snippet I provided is just one example, but I have multiple instances of this pattern throughout my codebase. My primary concern is that during development and testing, confidential non-production API keys are embedded in the code when using the MOCK_SYSTEM flag. These non-production API keys are sensitive and should not be exposed outside of the development and testing environments. While I want to maintain the ability to switch between mock and real requests for testing and development purposes, I'm looking for a more secure and organized way to handle this.

How can I securely manage conditional compilation in Swift code with a DEBUG MOCK_SYSTEM flag while ensuring that confidential non-production API keys are not exposed in the development and testing process?

Are there security best practices or tools for handling sensitive configuration data, such as API keys, in development and testing environments?

Is there a design pattern or architecture that can help centralize this behavior without exposing confidential non-production API keys in the codebase?

Are there Swift libraries or tools that can simplify the management of mock data and real network requests while addressing the security concern related to confidential API keys?

I'm looking for guidance on how to refactor this code to make it more secure, maintainable, and organized while addressing my concern about exposing confidential non-production API keys. Any advice, recommended practices, or tools would be greatly appreciated. Thank you!

6
  • Your title mentions "security" but nowhere in the body of your question do you mention what security concerns you have - specifically what threats do you believe you may be opening yourself up to with this? Sep 6 at 15:52
  • Hi, apologies, we would be mocking responses that contain ID's that are specific for us and do not want to expose to production build
    – Derek
    Sep 6 at 15:54
  • [ Please edit that into your question rather than leaving it in a comment; comments are ephemeral ] Sep 6 at 15:56
  • Edited the question. Thanks!
    – Derek
    Sep 6 at 15:56
  • I'm confused by the question. Based on its structure it seems that it is the mock logic which contains the API key? Why would it, since it's a mock? I also don't see you using any API related values in your #if MOCK_SYSTEM segment. Can you provide an example of the specific value that you don't want to expose, and why? (obviously you don't have to provide the correct value, just an example one is fine)
    – Flater
    Sep 7 at 22:39

1 Answer 1

5

Rather than sprinkle such conditionals throughout your program, refactor the code so that all communication goes through a single, minimal communications specialist. Then replace that specialist with an even simpler pseudo-communicator when testing.

In other words, use dependency injection - this is exactly what it's for.

2
  • Great tip, and definitely what I would suggest doing; but it's not an answer to the question that is being asked. This seems better suited to be a comment to the question.
    – Flater
    Sep 6 at 23:07
  • The point of mocking here is that you abstract away real-life interactors, so that your test suite doesn't have to contain real-life secrets. Sep 7 at 7:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.