맞춤 앱 권한 정의

이 문서에서는 앱 개발자가 Android에서 제공되는 보안 기능을 사용하여 자체 권한을 정의하는 방법을 설명합니다. 맞춤 권한을 정의하면 앱이 리소스와 기능을 다른 앱과 공유할 수 있습니다. 권한에 관한 자세한 내용은 권한 개요를 참고하세요.

배경

Android는 권한이 구분된 운영체제로, 각 앱이 고유한 시스템 ID(Linux 사용자 ID 및 그룹 ID)로 실행됩니다. 또한 시스템의 부분도 고유한 ID로 분리됩니다. 따라서 Linux는 앱을 서로 분리하고 시스템으로부터도 분리합니다.

앱은 다른 앱이 요청할 수 있는 권한을 정의하여 다른 앱에 기능을 노출할 수 있습니다. 또한 동일한 인증서로 서명된 다른 앱이 자동으로 사용할 수 있는 권한을 정의할 수도 있습니다.

앱 서명

모든 APK는 비공개 키를 개발자가 보유한 인증서로 서명해야 합니다. 인증서는 인증 기관에서 서명하지 않아도 됩니다. Android 앱이 자체 서명된 인증서를 사용하는 것은 일반적이며 허용됩니다. Android의 인증서 목적은 앱 작성자를 구분하는 것입니다. 이를 통해 시스템이 서명 수준 권한에 관한 앱 액세스를 허용하거나 거부하고 다른 앱과 동일한 Linux ID을 지정해 달라는 앱의 요청을 허용하거나 거부할 수 있습니다.

기기 제조 시점 후에 서명 권한 부여

Android 12(API 수준 31)부터, 서명 수준 권한의 knownCerts 속성을 사용하여 선언 시점에 알려진 서명 인증서의 다이제스트를 참조할 수 있습니다.

knownCerts 속성을 선언하고 앱의 protectionLevel 속성에서 특정 서명 수준 권한에 대해 knownSigner 플래그를 사용할 수 있습니다. 그러면 시스템이 현재 서명자를 비롯하여 요청 앱의 서명 계보에 있는 서명자가 knownCerts 속성의 권한으로 선언된 다이제스트 중 하나와 일치하면 요청 앱에 권한을 부여합니다.

knownSigner 플래그는 기기와 앱이 기기 제조 및 출하 시점에 앱에 서명하지 않았더라도 다른 앱에 서명 권한을 부여하도록 지원합니다.

사용자 ID 및 파일 액세스

설치 시 Android는 각 패키지에 고유한 Linux 사용자 ID를 제공합니다. ID는 패키지가 기기에 설치되어 있는 동안 동일하게 유지됩니다. 다른 기기에서는 동일한 패키지가 다른 UID를 가질 수 있습니다. 중요한 것은 지정된 기기에서는 각 패키지가 고유한 UID를 갖는다는 점입니다.

보안이 프로세스 수준에서 시행되기 때문에 두 패키지의 코드는 일반적으로 동일한 프로세스에서 실행할 수 없습니다. 두 패키지가 다른 Linux 사용자로 실행되어야 하기 때문입니다.

앱에 저장된 데이터는 그 앱의 사용자 ID를 할당받고 대개 다른 패키지에는 액세스할 수 없습니다.

Android 보안 모델에 관한 자세한 내용은 Android 보안 개요를 참고하세요.

권한 정의 및 적용

자체 권한을 적용하려면 먼저 하나 이상의 <permission> 요소를 사용하여 AndroidManifest.xml에서 권한을 선언해야 합니다.

이름 지정 규칙

모든 패키지가 동일한 인증서로 서명되지 않은 한, 여러 패키지가 같은 이름의 권한을 선언할 수 없습니다. 특정 패키지가 권한을 선언하면 다른 패키지가 첫 번째 패키지와 동일한 인증서로 서명되지 않는 한, 사용자는 동일한 권한 이름을 가진 다른 패키지를 설치할 수 없습니다.

도메인 스타일의 이름을 역순으로 사용하여 앱의 패키지 이름으로 권한 접두사를 지정하는 것이 좋습니다. 그 뒤에는 .permission.을 지정하고, 권한이 상위 SNAKE_CASE에서 나타내는 기능에 대한 설명을 입력하세요. 예: com.example.myapp.permission.ENGAGE_HYPERSPACE

이 권장사항을 따르면 이름이 충돌하는 것을 방지할 수 있고 소유자와 맞춤 권한의 의도를 명확하게 식별할 수 있습니다.

예를 들어, 자신의 활동을 시작할 수 있는 다른 앱을 제어해야 하는 앱의 경우 다음과 같이 이 작업에 대해 권한을 선언할 수 있습니다.

<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.myapp" >
    
    <permission
      android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
      android:label="@string/permlab_deadlyActivity"
      android:description="@string/permdesc_deadlyActivity"
      android:permissionGroup="android.permission-group.COST_MONEY"
      android:protectionLevel="dangerous" />
    ...
</manifest>

연결된 문서에 설명된 것처럼 protectionLevel은 필수 속성으로, 사용자에게 권한을 요구하는 앱이 있음을 알려주는 방식과 그 권한을 가질 수 있는 앱이 누구인지 시스템에 알려줍니다.

android:permissionGroup 속성은 선택사항으로, 사용자에게 권한을 표시하는 데에만 사용됩니다. 대부분의 경우 이 속성을 표준 시스템 그룹(android.Manifest.permission_group에 나와 있음)으로 설정하는 것이 좋지만, 다음 섹션에 설명된 것처럼 직접 그룹을 정의할 수도 있습니다. 사용자에게 표시되는 권한 UI가 간소화되도록 기존 그룹을 사용하는 것이 권장됩니다.

권한의 라벨과 설명을 모두 제공해야 합니다. 이러한 항목은 사용자가 권한 목록(android:label ) 또는 단일 권한에 관한 세부정보(android:description)를 볼 때 표시되는 문자열 리소스입니다. 라벨은 짧아야 하고 권한을 통해 보호되는 핵심 기능을 설명하는 몇 단어로 구성되어야 합니다. 설명은 그 권한이 소유자에게 어떠한 작업을 허용하는지 설명하는 두 개의 문장이어야 합니다. 규칙에 따라 두 문장으로 된 설명이어야 합니다. 첫 번째 문장에서는 권한을 설명하고, 두 번째 문장에서는 앱에 그 권한이 부여될 경우 문제가 발생할 가능성이 있는 작업 유형을 사용자에게 경고합니다.

다음은 CALL_PHONE 권한의 라벨과 설명의 예입니다.

<string name="permlab_callPhone">directly call phone numbers</string>
<string name="permdesc_callPhone">Allows the app to call non-emergency
phone numbers without your intervention. Malicious apps may cause unexpected
calls on your phone bill.</string>

권한 그룹 만들기

이전 섹션에서 설명한 것처럼 android:permissionGroup 속성을 사용하여 시스템이 사용자에게 권한을 설명하도록 할 수 있습니다. 대부분의 경우 이 속성을 표준 시스템 그룹(android.Manifest.permission_group에 나와 있음)으로 설정하는 것이 좋지만 <permission-group>을 사용하여 자체 그룹을 정의할 수도 있습니다.

<permission-group> 요소는 권한 집합의 라벨을 정의합니다. 이때 권한은 <permission> 요소를 통해 매니페스트에서 선언된 권한과 다른 곳에서 선언된 권한이 모두 포함됩니다. 이 작업은 사용자에게 표시되는 권한의 그룹화 방식에만 영향을 줍니다. <permission-group> 요소는 그룹에 속한 권한은 지정하지 않지만 그 그룹에 이름을 부여합니다.

그룹 이름을 <permission> 요소의 permissionGroup 속성에 할당하여 그룹에 권한을 부여할 수 있습니다.

<permission-tree> 요소는 코드에 정의된 권한 그룹의 네임스페이스를 선언합니다.

맞춤 권한 권장사항

<uses-permission> 요소를 정의하여 앱의 맞춤 권한을 정의하고 다른 앱에 맞춤 권한을요청할 수 있습니다. 하지만 맞춤 권한을 어떤 경우에 정의하고 요청할 것인지는 신중히 판단해야 합니다.

  • 기능을 서로 노출하는 앱 모음을 설계하는 경우 각 권한이 한 번만 정의되도록 앱을 설계해 봅니다. 앱이 모두 동일한 인증서로 서명되지 않은 경우에 이 작업을 실행해야 합니다. 앱이 모두 동일한 인증서로 서명되더라도 각 권한을 한 번만 정의하는 것이 좋습니다.
  • 제공하는 앱과 동일한 서명으로 서명된 앱에만 사용 가능한 기능인 경우 서명 확인을 사용하기 때문에 맞춤 권한을 정의하지 않아도 됩니다. 앱 중 하나가 다른 앱에 요청을 하면 다른 앱은 요청을 따르기 전에 서로 동일한 인증서로 서명되었는지 확인할 수 있습니다.

맞춤 권한이 필요한 경우, 권한 확인을 실행하는 애플리케이션의 개발자와 같은 개발자가 서명한 애플리케이션만 권한에 액세스해야 하는지 살펴보세요(예: 같은 개발자의 두 애플리케이션 사이에 보안 프로세스 간 통신을 구현하는 경우). 이 경우라면 서명 권한을 사용하는 것이 좋습니다. 서명 권한은 사용자에게 투명하게 공개되며, 사용자에게 혼동을 유발할 수 있는 사용자 확인 권한을 방지합니다.

계속 읽기:

<uses-permission>
앱의 필수 시스템 권한을 선언하는 매니페스트 태그에 관한 API 참조입니다.

관련 항목:

Android 보안 개요
Android 플랫폼의 보안 모델을 자세히 설명합니다.