Manifest & Permissions

uses-permission vs permission: Declaring Access vs Defining a Capability

<uses-permission> requests access to an existing permission. <permission> defines a permission that your app can use to protect its own exposed functionality. Confusing the two can leave a feature inaccessible—or expose an interface without the protection you intended.

By , FounderUpdated 3 min read

Read the two declarations as different contracts

XML · REFERENCE EXAMPLE
<uses-permission android:name="android.permission.CAMERA" />

This declares that the application may need camera access. It does not define the camera permission or grant it automatically when a runtime grant is required.

XML · REFERENCE EXAMPLE
<permission
    android:name="com.example.app.permission.INTERNAL_SYNC"
    android:protectionLevel="signature" />

This illustrative custom permission defines a capability in your namespace. A component must also reference the permission where enforcement is intended; defining it alone does not protect every app action.

Protect the correct boundary

Situation Relevant declaration
App reads a protected platform resource uses-permission plus the required runtime flow
App exposes a service to trusted companion apps Define an appropriate custom permission and apply it to the service
App consumes another app's protected provider Request that provider's permission and satisfy its protection level
App has only internal components Prefer avoiding unnecessary exported interfaces

Consult the manifest documentation and permission reference for exact attribute behavior.

Choose a custom protection level deliberately

A signature-level permission can be appropriate for a controlled family of apps sharing a trusted signing relationship. It is not a generic way to authorize arbitrary third-party partners. Consider key rotation, distribution and the actual caller identities before designing the interface.

A normal custom permission should not be treated as a strong security boundary for sensitive operations. Enforce business authorization where the protected data or operation is accessed.

Inspect merged declarations

Dependencies can add requests or definitions. Use the merged manifest to identify the source and ensure that permission names are fully qualified and do not accidentally collide with another component's contract.

Test both allowed and denied callers

Exercise the component from an authorized test app and an unauthorized one. Confirm that legitimate use still works and that untrusted callers cannot perform the protected action.

APKLint's Manifest Checker helps review the XML, but it cannot validate your signing relationships or backend authorization. Preserve runtime evidence alongside the declaration review.

Connect a permission definition to the protected service

Imagine a suite containing a notes app and a trusted synchronization companion. The notes app defines a namespaced permission and applies it to the service that accepts synchronization requests. The companion declares that it uses that permission. Defining the name in one manifest without assigning it to the service leaves the intended boundary unenforced.

The permission-element reference describes definition and protection level, while the uses-permission reference describes an application's request to use a capability. Check the final merged declarations in both built applications rather than relying only on their source manifests.

Test the signing relationship that actually ships

For a signature-protected interface, use the real supported signing arrangement in a controlled test distribution. Development certificates and store-distributed certificates can differ, so a debug-to-debug success does not automatically validate the production pair. If keys are rotated, review the platform's supported signing and permission behavior for the devices the suite supports.

Exercise an authorized companion and a separate unauthorized test application. The authorized request should reach the intended operation, while the unauthorized caller should be rejected before private data or side effects are exposed. Also test malformed input from the trusted caller: permission to reach a service does not make every supplied file path or record identifier valid.

Keep component exposure narrow. If the service is entirely internal, an unnecessary exported interface and custom permission may add complexity without serving a product need. For an intentionally shared interface, document the contract, caller requirements and data-level authorization. Test both a read and a state-changing request if both are exposed, including failure behavior that does not reveal protected record contents. Retain the artifact identities and signing evidence with the result. Manifest inspection can confirm that the definition and request exist, but runtime tests establish whether the distributed applications interact under the intended trust relationship.

Sources and further reading

  1. Android Developers: App manifest overview
  2. Android Developers: Manifest.permission reference

Reference review: 29 September 2026. Examples illustrate the workflow; check your installed versions, release artifact and account-specific Console requirements before applying them. This guide is not a claim that APKLint executed your project or verified your private account.

APKLint

Android inspection tools and practical release guides. About APKLint · Report a correction