App Testing & Deployment

Chapter 10
Code Signing, Provisioning, and Build Configuration

Certificate in IOS Development
App Testing & Deployment   •   Certificate

Code Signing, Provisioning, and Build Configuration

Introduction

An iOS application is not merely compiled source code. Before it can run on a physical device or be distributed through TestFlight, the App Store, an alternative distribution channel where applicable, or an organization’s internal deployment system, it must be associated with an identity and authorized for a particular purpose. Apple’s code-signing system provides that association.

Code signing, provisioning, entitlements, and build configuration form a connected release system. Code signing establishes who created or authorized an executable and helps detect modification. Provisioning determines whether the executable may run in a particular context. Entitlements declare protected capabilities. Build settings determine how source code becomes an application bundle and which identifiers, versions, and signing resources are used.

A developer who understands only Xcode’s automatic signing may successfully run a first application but struggle when managing multiple targets, environments, teams, extensions, CI pipelines, or release variants. This chapter develops the conceptual and practical foundation needed to configure, archive, export, and securely distribute iOS applications.

Learning Objectives

By the end of this chapter, you should be able to:

  • explain the relationship among bundle identifiers, certificates, provisioning profiles, entitlements, and code signatures;
  • distinguish development, testing, and distribution signing contexts;
  • configure targets, schemes, build configurations, and important build settings;
  • manage application and extension identifiers consistently;
  • create reproducible archives and select suitable export options;
  • apply versioning and build-number practices;
  • diagnose common signing and provisioning failures; and
  • protect certificates, private keys, API credentials, and signing assets in development and continuous-integration environments.

1. The iOS Trust and Authorization Model

1.1 Code signing

Code signing applies a digital signature to an executable and associated code resources. The signature is produced using a private key and can be checked using the corresponding public key and certificate chain. In simplified terms, a verifier checks that:

  1. the signature was generated by the holder of the private key;
  2. the certificate is issued by a trusted Apple certificate authority chain;
  3. the signed content has not changed since signing; and
  4. the application is authorized for its intended execution or distribution context.

A signature does not by itself grant every application capability. Signing proves identity and integrity; provisioning and entitlements establish authorization for particular uses.

1.2 Bundle identifiers

A bundle identifier uniquely names an application target within Apple’s developer ecosystem. A typical identifier is reverse-domain style, such as com.example.weatherapp. The identifier appears in the application’s Info.plist as CFBundleIdentifier, although its final value is normally supplied through the PRODUCT_BUNDLE_IDENTIFIER build setting.

The application target, App ID or associated identifier in the Apple Developer account, provisioning profile, and entitlements must be compatible. A mismatch such as com.example.weatherapp.debug in the build while the profile authorizes only com.example.weatherapp commonly produces a signing failure.

Extensions, widgets, notification service extensions, and watch targets normally require their own bundle identifiers. Their identifiers may use a related prefix, but they are separate targets and must be signed and provisioned separately.

1.3 Certificates and private keys

A certificate binds a public key to an Apple-recognized signing identity. The private key remains confidential and is used to create signatures. A certificate file without its matching private key is insufficient for signing.

Common signing contexts include:

ContextTypical purpose
Apple DevelopmentRunning and debugging on registered devices; development provisioning
Apple DistributionApp Store, TestFlight, and applicable distribution workflows
Developer ID ApplicationNot an iOS signing identity; used for specific macOS distribution scenarios

Certificate names and available workflows can change as Apple updates its developer services. Xcode’s current signing identity options and Apple Developer documentation should be treated as authoritative. Development and distribution certificates should be issued only to people or systems that require them.

1.4 Provisioning profiles

A provisioning profile is a signed authorization document that connects a team, application identifier, signing certificate, permitted entitlements, and sometimes a set of registered devices. A development profile commonly supports device testing. A distribution profile authorizes a distribution method and does not function as a general development profile.

A profile is not the application and is not a substitute for a certificate. Rather, it is an authorization artifact used during signing and, depending on the distribution context, installation or validation.

Provisioning profiles may be managed automatically by Xcode or managed explicitly in the Apple Developer portal. Automatic signing reduces administrative work, while manual signing offers greater control and is often useful for complex projects, regulated build environments, or tightly controlled CI systems.

2. Entitlements and Capabilities

2.1 Entitlements

Entitlements are key-value declarations embedded in the signed application. They request access to platform features or services that require authorization. Examples include associated domains, application groups, push notifications, keychain access groups, iCloud containers, and certain communication or payment capabilities.

An entitlement is not simply a permission that a developer may type into a file. The capability must be enabled for the relevant App ID, the target must declare it appropriately, the provisioning profile must authorize it, and the final signature must contain a compatible value.

The effective entitlements of a signed product should be inspected rather than inferred solely from project settings. For example, a target may have a capability enabled in Xcode while a stale profile does not contain the corresponding authorization.

2.2 Capabilities and least privilege

Xcode’s Signing & Capabilities interface provides a convenient way to configure many entitlements. Enabling a capability may modify project settings, create or update an entitlements file, and require a corresponding change in the Apple Developer account.

The principle of least privilege requires enabling only the capabilities genuinely needed by the application. Excess entitlements increase operational complexity and may increase privacy, security, or review risk. A capability should therefore be documented by purpose, owner, environment, and required Apple-side configuration.

Typical relationships include:

CapabilityRelated configuration concern
Push NotificationsAPNs environment and server credentials; application identifier
Associated DomainsDomain association file and approved domains
App GroupsShared group identifier used by related targets
Keychain SharingAccess-group consistency and keychain behavior
Sign in with AppleService identifiers, configuration, and server-side validation
iCloudContainers, services, and environment configuration

The exact entitlement keys and platform behavior vary by SDK and capability. Developers should not copy entitlement files between unrelated applications without reviewing every value.

3. Automatic and Manual Signing

With automatic signing, Xcode attempts to select or create suitable signing resources based on the selected team, bundle identifier, target, configuration, and destination. This is usually appropriate for introductory development and many ordinary projects.

Manual signing explicitly selects the signing certificate and provisioning profile for each relevant target and build configuration. It can make a build more reproducible, but it also creates maintenance responsibility. Every target, extension, configuration, and distribution method must be reviewed when profiles expire or capabilities change.

A useful decision rule is:

  • use automatic signing for straightforward local development when the team accepts Xcode-managed resources;
  • use manual or carefully controlled signing for release pipelines, multiple teams, complex target graphs, and environments requiring deterministic inputs; and
  • avoid mixing automatic and manual signing casually across application and extension targets.

The project’s signing configuration should be recorded in source control where safe. Private keys and secret credentials must never be committed to the repository.

4. Targets, Schemes, and Build Configurations

4.1 Targets

A target defines a product to build, such as the main application, a widget, or a test bundle. Each target has source files, resources, dependencies, bundle settings, signing settings, and build phases. A project may contain several targets with different bundle identifiers and entitlements.

4.2 Build configurations

A build configuration is a named collection of settings. Debug and Release are conventional defaults, but teams may create configurations such as Staging, QA, or Enterprise when a clear operational distinction exists.

Configuration differences should be intentional. Examples include:

  • compiler optimization and debugging information;
  • API base URL or service environment;
  • feature flags;
  • logging level;
  • bundle identifier suffixes;
  • signing identity and provisioning profile; and
  • inclusion of test or diagnostic resources.

Environment-specific behavior should not depend on developers manually editing source code before a release. Instead, use configuration files, build settings, generated configuration, or a controlled build-time mechanism.

4.3 Schemes

A scheme tells Xcode which targets to build, in what order, and how to run, test, profile, archive, or analyze them. Shared schemes should be committed when they are part of the team’s build process. A scheme that exists only on one developer’s machine can make local success difficult to reproduce in CI.

Archiving uses the scheme’s Archive action and normally selects the Release configuration. A successful Run action does not prove that the Archive action is correctly configured.

4.4 Build settings

Important settings include:

  • PRODUCT_BUNDLE_IDENTIFIER: final identifier for the target;
  • PRODUCT_NAME: product name;
  • MARKETING_VERSION: human-facing version, such as 2.4.0;
  • CURRENT_PROJECT_VERSION: build number, such as 137;
  • CODE_SIGN_STYLE: automatic or manual signing behavior;
  • DEVELOPMENT_TEAM: selected Apple Developer team;
  • CODE_SIGN_IDENTITY: signing identity selection;
  • PROVISIONING_PROFILE_SPECIFIER: selected profile when manual signing is used;
  • INFOPLIST_FILE: source property-list file; and
  • SWIFT_VERSION, deployment target, and architecture-related settings.

Build settings can be specified in the project, target, configuration file, scheme action, or command line. Their precedence can be difficult to understand; therefore, inspect the resolved settings for the actual target and configuration rather than relying on one visible project field.

.xcconfig files are useful for declaring shared settings. Sensitive values should not be stored in them in source control. A configuration file may refer to environment variables or CI-provided values, but the resulting build must still be auditable.

5. Versioning and Identity

Two values are especially important:

  • the marketing version, displayed to users, such as 1.3.0; and
  • the build number, identifying a particular submitted or distributed build, such as 42.

A common release policy requires that each uploaded build number be unique within the relevant application version. Teams should define whether build numbers increase globally, per marketing version, or according to a CI sequence. The policy must be compatible with Apple’s submission rules and the team’s operational tools.

Semantic versioning can be expressed as MAJOR.MINOR.PATCH, but Apple does not require every team to use that exact scheme. The important requirements are consistency, traceability, and communication. A release record should connect the bundle identifier, marketing version, build number, commit or source revision, configuration, and signing context.

For example, a release might be recorded as:

FieldValue
Bundle identifiercom.example.weatherapp
Marketing version2.4.0
Build number137
ConfigurationRelease
Source revisionGit commit recorded by CI
DistributionTestFlight

6. Archives and Export Options

6.1 The archive

An archive is a structured Xcode output containing the built application and metadata needed for later validation, signing, and distribution. It is more than an ordinary .app produced by a Run action. Archives support a separation between building and exporting: a controlled build can be archived once and exported for an intended distribution method.

A typical command-line archive operation is conceptually similar to:

xcodebuild archive \
  -workspace Weather.xcworkspace \
  -scheme Weather \
  -configuration Release \
  -archivePath build/Weather.xcarchive

The exact command depends on the project, workspace, destination, SDK, and signing strategy. The archive should be validated before export and retained according to the team’s release policy.

6.2 Export methods

Export options describe how an archive is converted into a distributable product. Depending on the application and current Apple rules, methods may include App Store submission, TestFlight/App Store distribution, development, ad hoc distribution, or other supported organizational methods.

The chosen method determines signing and installation behavior. A development export is not equivalent to an App Store submission, and an ad hoc export normally depends on registered devices. Export settings should be treated as release metadata rather than as an arbitrary collection of flags.

An export-options property list might be generated by Xcode and reviewed by the release engineer. Teams should avoid blindly copying an old file because distribution methods, profiles, team identifiers, and signing requirements can change.

6.3 Validation

Before distribution, verify:

  • the archive was produced by the intended scheme and configuration;
  • the bundle identifier is correct;
  • the version and build number are correct;
  • all targets and extensions are included and correctly signed;
  • entitlements match the intended capabilities;
  • privacy declarations and required metadata are present;
  • the archive is free from unintended debug endpoints or test credentials; and
  • the exported artifact is tested in the same general distribution context in which users will receive it.

7. Secure Credential Handling

Signing systems contain high-value assets. A leaked private key, App Store Connect API key, distribution certificate, or CI secret may permit unauthorized signing, upload, or access to release systems.

7.1 Protecting signing material

Private keys should be stored in an approved password manager, encrypted keychain, or dedicated secrets system. Access should be role-based and limited to the people or services that require it. Certificates and profiles may be less sensitive than private keys, but they should still be controlled because they reveal project and team information and can facilitate misuse when combined with keys.

Do not commit the following to source control:

  • .p12 files containing private keys;
  • unprotected private keys;
  • App Store Connect API private keys;
  • passwords for certificate files;
  • provisioning profiles when organizational policy prohibits them; or
  • production service credentials embedded in source or configuration files.

A .gitignore entry is not a complete security control because a secret may already exist in repository history. If exposure occurs, revoke or rotate the affected credential and investigate access logs.

7.2 CI/CD practice

A secure CI system should use an ephemeral or isolated keychain where practical, inject secrets only at job runtime, minimize log output, and remove temporary files after the job. The pipeline should use a dedicated Apple account or API key with the least privilege supported by the workflow.

Build agents should be trusted, patched, access-controlled, and separated from unrelated workloads. Signing should occur only after tests and static checks succeed. The pipeline should record who initiated the build, which source revision was built, which configuration was used, and which artifact was produced, without printing secret values.

7.3 Ethical and governance considerations

Signing an application under another person’s identity without authorization undermines software provenance and may expose users to malicious updates. Organizations should define approval boundaries for production signing, maintain an inventory of certificates and profiles, establish revocation procedures, and review access when staff or vendors leave.

Privacy and security capabilities also carry governance obligations. For example, push notifications, location services, associated domains, and keychain sharing should be justified, documented, and tested against the application’s privacy commitments. A technically valid entitlement can still be inappropriate if the application’s behavior or disclosures do not justify it.

8. A Practical Release Workflow

A dependable workflow separates configuration, compilation, signing, validation, and distribution:

  1. Define identity. Confirm the target and bundle identifier.
  2. Select the team. Verify the intended Apple Developer team and account.
  3. Configure capabilities. Enable only required capabilities and check Apple-side identifiers.
  4. Choose signing mode. Decide whether automatic or manual management is appropriate.
  5. Configure the scheme. Ensure Archive uses the intended Release-like configuration.
  6. Set versions. Assign the marketing version and a unique build number.
  7. Build and test. Run unit, UI, integration, and device tests appropriate to the release.
  8. Archive. Produce an archive from a clean or controlled environment.
  9. Inspect. Check products, entitlements, identifiers, linked frameworks, and metadata.
  10. Export or upload. Use the intended method and credentials.
  11. Verify distribution. Install or access the result through the target channel and test critical flows.
  12. Record and retain. Store release notes, artifact hashes where appropriate, source revision, and approval information.

The workflow is intentionally explicit. Many release incidents occur because a developer tests a Debug build successfully and assumes that the archived Release product is identical.

9. Troubleshooting Signing Failures

“No signing certificate found”

The selected identity may be absent, expired, revoked, or missing its private key. Inspect the login keychain and confirm that the certificate and private key form a pair. On a CI agent, verify that the certificate was imported into the keychain available to the build process.

“Provisioning profile doesn’t include the application identifier”

Compare the resolved PRODUCT_BUNDLE_IDENTIFIER with the identifier authorized by the profile. Check for configuration-specific suffixes and ensure the profile belongs to the selected team.

“Entitlement not permitted”

The capability may not be enabled for the App ID, the profile may be stale, or the entitlement value may not match the authorized value. Reconcile the target capability, Apple Developer configuration, entitlements file, and selected profile.

“Requires a provisioning profile” or device installation failure

The build may have been exported for the wrong method, the device may not be registered where required, or the application and profile may target different environments. Inspect the export method and destination assumptions.

Extension signing failure

Every embedded extension must be signed. Check its own bundle identifier, team, profile, entitlements, and build configuration. A correctly signed main application cannot compensate for an incorrectly signed embedded target.

The most useful diagnostic principle is to inspect resolved build settings and the signed output. Do not rely only on the project editor’s labels, because inherited settings, configuration files, command-line overrides, and target-specific values may change the final product.

10. Illustrative Case: WeatherNow Release Pipeline

Background

WeatherNow is a small application with a main iOS target, a widget extension, and a notification service extension. The team uses Debug for local development and Release for TestFlight. Push Notifications, App Groups, and Associated Domains are required.

Problem

The application runs locally, but the TestFlight archive fails validation. The widget also fails to read shared data in a development build. The team discovers that the main application uses com.northstar.weathernow, while the Release widget identifier was accidentally changed to com.northstar.weather. In addition, the Release profile predates the App Groups capability.

Analysis

The team maps each target separately:

TargetIdentifierCapabilitiesRelease requirement
Main appcom.northstar.weathernowPush, App Groups, DomainsDistribution signing
Widgetcom.northstar.weathernow.widgetApp GroupsDistribution signing
Notification extensioncom.northstar.weathernow.notificationPush-related processingDistribution signing

The team compares resolved identifiers, entitlements, profiles, and signing identities for Debug and Release. It finds that the widget’s shared group entitlement is correct in Debug but absent from the old Release profile.

Approach and solution

The release engineer restores the intended widget identifier, confirms that each identifier exists in the developer account, enables the required capabilities for the correct App IDs, and regenerates or refreshes the appropriate profiles. The team then archives using the shared Release scheme, inspects the archive, and validates all embedded targets.

The CI pipeline assigns the build number, imports signing material into an ephemeral keychain, builds from a protected revision, and uploads only after automated tests pass. The pipeline stores the archive’s source revision and release metadata but does not print credentials.

Outcome

The archive passes validation, the widget reads the shared App Group data, and the TestFlight build is available for review. The team adds a target matrix and a pre-archive check that compares each target’s identifier and required capabilities with the release manifest.

Learning points

  1. Signing is a property of every signed target, not just the main application.
  2. Debug success does not prove Release correctness.
  3. Entitlements must be consistent across project configuration, Apple-side authorization, profiles, and final output.
  4. A release manifest and automated checks reduce configuration drift.
  5. Secure CI handling is part of application quality, not an administrative afterthought.

11. Contemporary Practices and Limitations

Apple increasingly supports workflows in which Xcode manages signing resources and teams use App Store Connect APIs or automated distribution tools. These conveniences reduce manual work but do not eliminate the need to understand identity, authorization, or credential scope. An automated system can reproduce an incorrect configuration quickly.

Cloud-based CI can improve repeatability, but it introduces trust, data-residency, vendor-access, and secret-management questions. Teams should evaluate where private keys are stored, who can trigger production signing, how logs are protected, and how artifacts are deleted.

AI-assisted coding and configuration tools can generate build settings or entitlement files, but generated configuration must be reviewed. An assistant may invent a capability, copy an identifier from another project, or expose a secret in a diagnostic response. The authoritative sources remain the project’s resolved settings, Apple’s current documentation, signed artifacts, and controlled validation results.

Best-Practice Checklist

  • Give every target a deliberate, documented bundle identifier.
  • Treat certificates, private keys, profiles, and API keys as controlled assets.
  • Enable only required capabilities and review their entitlements.
  • Keep Debug, Release, and staging differences explicit.
  • Share schemes and configuration files required for reproducible builds.
  • Use unique, traceable build numbers.
  • Archive with the intended scheme and inspect the archive before export.
  • Validate every embedded target, not only the main application.
  • Use least-privilege credentials and ephemeral CI environments where practical.
  • Rotate exposed or departing-user credentials promptly.
  • Test the exported product in its actual distribution context.
  • Record the source revision, configuration, versions, and release approvals.

Chapter Summary

Code signing establishes application identity and integrity, while provisioning profiles authorize a signed product for a particular team, identifier, capability set, device context, or distribution method. Bundle identifiers connect targets to Apple-side application records, certificates identify signing authorities, and entitlements request protected capabilities. Every application, extension, widget, and test-related product must be considered in the signing design.

Automatic signing is convenient; manual signing offers explicit control but increases maintenance responsibility. Targets, schemes, build configurations, and resolved build settings determine whether a local build and a release archive are actually equivalent. Marketing versions communicate product releases, while build numbers distinguish individual artifacts. Archives provide a controlled boundary between building and exporting.

Reliable deployment depends on inspecting signed output, validating entitlements, using appropriate export methods, and protecting private keys and API credentials. Secure CI, least privilege, release traceability, and explicit approval processes are essential parts of professional iOS delivery.

Key Terms

Bundle identifier: A unique identifier assigned to an application target.

Certificate: A signed document binding a public key to an Apple-recognized identity.

Private key: Secret cryptographic material used to create digital signatures.

Code signing: The process of signing code to establish identity and detect modification.

Provisioning profile: An authorization document connecting a team, identifier, certificate, entitlements, and distribution or device context.

Entitlement: A signed key-value declaration requesting a protected platform capability.

Capability: An Xcode and Apple Developer configuration representing a platform service or authorization.

App ID: Apple-side application identity associated with a bundle identifier and team.

Target: A project definition that produces an application, extension, test bundle, or other product.

Scheme: Instructions describing targets and actions for building, running, testing, profiling, or archiving.

Build configuration: A named set of build settings, such as Debug or Release.

Build setting: A parameter controlling compilation, packaging, signing, or product metadata.

Archive: A structured Xcode output containing a built product and release metadata.

Export method: The distribution context used to convert an archive into a deliverable product.

Marketing version: User-facing application version, commonly stored in CFBundleShortVersionString.

Build number: Identifier for a particular build, commonly stored in CFBundleVersion.

Automatic signing: Xcode-managed selection or creation of signing resources.

Manual signing: Explicit selection of certificates and provisioning profiles.

Ephemeral keychain: Temporary protected keychain used by an automated build job.

Least privilege: Security principle of granting only the access required for a task.

Review Questions

Short Answer Questions

  1. What is the relationship between a certificate, its private key, and a code signature?
  2. Why does an application extension normally require its own bundle identifier and signing configuration?
  3. What is the difference between a marketing version and a build number?
  4. Name two risks associated with committing signing credentials to source control.
  5. Why should developers inspect resolved build settings rather than only the Xcode project editor?

Long Answer Questions

  1. Explain how bundle identifiers, certificates, provisioning profiles, and entitlements cooperate during an iOS release.
  2. Compare automatic and manual signing, including appropriate use cases and maintenance risks.
  3. Describe a professional workflow from configuring capabilities through archiving, exporting, validating, and recording a release.
  4. Explain how targets, schemes, and build configurations support multiple environments such as development, staging, and production.
  5. Discuss secure credential handling in a CI/CD pipeline for iOS applications.

Analytical / Application Questions

  1. A Debug build runs successfully, but the Release archive reports that an entitlement is not permitted. Identify the configuration layers you would inspect and explain the order of your investigation.
  2. A project contains a main app and two extensions. Design a compact release manifest showing the identifiers, capabilities, signing context, version values, and validation checks that should be recorded for each target.
  3. A team wants to move from local manual signing to cloud CI. Analyze the security and reproducibility issues it should resolve before allowing automated production signing.

Multiple Choice Questions with Answers

Question 1

Which artifact primarily connects a signing certificate, application identifier, entitlements, and a permitted execution or distribution context?

A. Provisioning profile

B. Source control tag

C. Storyboard file

D. Crash report

Correct Answer: A. Provisioning profile

Question 2

What is the main purpose of a bundle identifier?

A. To store the application’s display icon

B. To uniquely name an application target in Apple’s ecosystem

C. To encrypt network traffic

D. To determine the device screen size

Correct Answer: B. To uniquely name an application target in Apple’s ecosystem

Question 3

Which statement about an iOS private signing key is correct?

A. It may safely be committed to a public repository

B. It is used to create signatures and must be protected

C. It is the same as the marketing version

D. It replaces the provisioning profile

Correct Answer: B. It is used to create signatures and must be protected

Question 4

What does an entitlement represent?

A. A request for an authorized protected capability

B. A user’s App Store review comment

C. A source-code formatting rule

D. A device’s battery percentage

Correct Answer: A. A request for an authorized protected capability

Question 5

Which setting commonly identifies the human-facing application version?

A. CURRENT_PROJECT_VERSION

B. PRODUCT_BUNDLE_IDENTIFIER

C. MARKETING_VERSION

D. CODE_SIGN_STYLE

Correct Answer: C. MARKETING_VERSION

Question 6

Why is an archive different from an ordinary application built for Run?

A. An archive is a structured release output suitable for later validation and export

B. An archive cannot contain application resources

C. An archive is always unsigned

D. An archive is used only for unit tests

Correct Answer: A. An archive is a structured release output suitable for later validation and export

Question 7

A widget works in Debug but fails in Release because shared data is unavailable. Which issue is most directly relevant?

A. The Release target may lack the correct App Group entitlement or profile authorization

B. The marketing version is too short

C. The source code contains comments

D. The device has a different wallpaper

Correct Answer: A. The Release target may lack the correct App Group entitlement or profile authorization

Question 8

Which practice best supports secure CI signing?

A. Print all private keys in build logs for debugging

B. Use an ephemeral protected keychain and inject secrets only at job runtime

C. Share one unrestricted account with every developer

D. Store certificate passwords in application source code

Correct Answer: B. Use an ephemeral protected keychain and inject secrets only at job runtime

Question 9

What does a scheme primarily define?

A. The application’s legal privacy policy

B. The targets and actions used for building, testing, running, and archiving

C. The Apple certificate authority hierarchy

D. The device’s cellular plan

Correct Answer: B. The targets and actions used for building, testing, running, and archiving

Question 10

What is the principle of least privilege in signing governance?

A. Grant every developer production signing access

B. Grant only the access required for a defined task

C. Disable all application capabilities

D. Use the oldest available certificate

Correct Answer: B. Grant only the access required for a defined task

App Testing & Deployment
Chapter 10 of 15