पसंद के मुताबिक ऐप्लिकेशन की अनुमति तय करना

इस दस्तावेज़ में बताया गया है कि ऐप्लिकेशन डेवलपर, अपनी अनुमतियों को तय करने के लिए, Android की दी गई सुरक्षा सुविधाओं का इस्तेमाल कैसे कर सकते हैं. पसंद के मुताबिक अनुमतियां तय करके, ऐप्लिकेशन अपने संसाधन और सुविधाओं को दूसरे ऐप्लिकेशन के साथ शेयर कर सकता है. अनुमतियों के बारे में ज़्यादा जानने के लिए, अनुमतियों की खास जानकारी देखें.

बैकग्राउंड

Android एक ऐसा ऑपरेटिंग सिस्टम है जिसमें हर ऐप्लिकेशन, अलग-अलग सिस्टम आइडेंटिटी (Linux यूज़र आईडी और ग्रुप आईडी) के साथ काम करता है. सिस्टम के हिस्सों को भी अलग-अलग पहचानों में बांटा जाता है. इस तरह, Linux ऐप्लिकेशन को एक-दूसरे और सिस्टम से अलग रखता है.

ऐप्लिकेशन, अन्य ऐप्लिकेशन के लिए अपनी सुविधाओं को तब दिखा सकते हैं, जब वे ऐसी अनुमतियां तय करें जिनका अनुरोध अन्य ऐप्लिकेशन कर सकते हैं. वे ऐसी अनुमतियां भी तय कर सकते हैं जो उसी सर्टिफ़िकेट से साइन किए गए किसी भी दूसरे ऐप्लिकेशन के लिए, अपने-आप उपलब्ध हो जाती हैं.

ऐप पर हस्ताक्षर

सभी APK को किसी सर्टिफ़िकेट से हस्ताक्षरित करना ज़रूरी है. साथ ही, यह भी ज़रूरी है कि उस सर्टिफ़िकेट की निजी पासकोड, डेवलपर के पास हो. सर्टिफ़िकेट पर, सर्टिफ़िकेट देने वाली संस्था या निकाय के हस्ताक्षर नहीं होने चाहिए. Android ऐप्लिकेशन के लिए, खुद हस्ताक्षर किए गए सर्टिफ़िकेट का इस्तेमाल करना आम बात है और इसकी अनुमति है. Android में सर्टिफ़िकेट का मकसद, ऐप्लिकेशन बनाने वाले लोगों को अलग-अलग पहचानना है. इससे सिस्टम, ऐप्लिकेशन को हस्ताक्षर-लेवल की अनुमतियों का ऐक्सेस दे सकता है या नहीं दे सकता. साथ ही, किसी ऐप्लिकेशन के दूसरे ऐप्लिकेशन की तरह ही Linux की पहचान पाने के अनुरोध को स्वीकार या अस्वीकार कर सकता है.

डिवाइस बनाने के बाद, हस्ताक्षर की अनुमतियां देना

Android 12 (एपीआई लेवल 31) से, हस्ताक्षर के लेवल पर अनुमतियों के लिए knownCerts एट्रिब्यूट की मदद से, एलान के समय, हस्ताक्षर करने के लिए इस्तेमाल किए जाने वाले जाने-पहचाने सर्टिफ़िकेट के डाइजेस्ट देखे जा सकते हैं.

आपके पास knownCerts एट्रिब्यूट का एलान करने का विकल्प है. साथ ही, हस्ताक्षर के लेवल की किसी खास अनुमति के लिए, अपने ऐप्लिकेशन के protectionLevel एट्रिब्यूट में knownSigner फ़्लैग का इस्तेमाल किया जा सकता है. इसके बाद, अगर अनुरोध करने वाले ऐप्लिकेशन के साइनिंग लाइनेज में मौजूद कोई साइनर, knownCerts एट्रिब्यूट में अनुमति के साथ एलान किए गए किसी एक डाइजेस्ट से मैच करता है, तो सिस्टम उस अनुमति को अनुरोध करने वाले ऐप्लिकेशन को देता है. इसमें मौजूदा साइनर भी शामिल है.

knownSigner फ़्लैग की मदद से, डिवाइस और ऐप्लिकेशन, दूसरे ऐप्लिकेशन को साइन करने की अनुमतियां दे सकते हैं. इसके लिए, डिवाइस बनाने और शिप करने के समय, ऐप्लिकेशन को साइन करने की ज़रूरत नहीं होती.

उपयोगकर्ता आईडी और फ़ाइल का ऐक्सेस

इंस्टॉल करते समय, Android हर पैकेज को एक अलग Linux यूज़र आईडी देता है. डिवाइस पर पैकेज के मौजूद रहने तक, उसकी पहचान एक जैसी रहती है. किसी दूसरे डिवाइस पर, एक ही पैकेज का यूआईडी अलग हो सकता है. अहम बात यह है कि किसी डिवाइस पर हर पैकेज का यूआईडी अलग होता है.

सुरक्षा की पुष्टि, प्रोसेस के लेवल पर की जाती है. इसलिए, आम तौर पर किसी एक प्रोसेस में दो पैकेज के कोड नहीं चलाए जा सकते. ऐसा इसलिए, क्योंकि उन्हें अलग-अलग Linux उपयोगकर्ताओं के तौर पर चलाना होता है.

किसी ऐप्लिकेशन से सेव किया गया डेटा, उस ऐप्लिकेशन के यूज़र आईडी से असाइन किया जाता है. आम तौर पर, अन्य पैकेज इस डेटा को ऐक्सेस नहीं कर सकते.

Android के सुरक्षा मॉडल के बारे में ज़्यादा जानने के लिए, Android की सुरक्षा के बारे में खास जानकारी देखें.

अनुमतियां तय करना और उन्हें लागू करना

अपनी अनुमतियां लागू करने के लिए, आपको सबसे पहले अपने AndroidManifest.xml में एक या उससे ज़्यादा <permission> एलिमेंट का इस्तेमाल करके, उन्हें एलान करना होगा.

नेमिंग कन्वेंशन

सिस्टम, एक ही नाम वाली अनुमति के लिए कई पैकेज को एलान करने की अनुमति नहीं देता. ऐसा तब तक नहीं किया जा सकता, जब तक सभी पैकेज पर एक ही सर्टिफ़िकेट से हस्ताक्षर न किया गया हो. अगर कोई पैकेज किसी अनुमति का एलान करता है, तो सिस्टम उपयोगकर्ता को उसी अनुमति के नाम वाले अन्य पैकेज इंस्टॉल करने की अनुमति भी नहीं देता. ऐसा तब तक नहीं होगा, जब तक उन पैकेजों पर उसी सर्टिफ़िकेट से हस्ताक्षर नहीं किया जाता जिससे पहले पैकेज पर हस्ताक्षर किया गया है.

हमारा सुझाव है कि अनुमतियों के नाम में ऐप्लिकेशन के पैकेज के नाम को पहले रखें. इसके लिए, रिवर्स-डोमेन-स्टाइल नेमिंग का इस्तेमाल करें. इसके बाद, .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 में मौजूद) पर सेट किया जाता है. हालांकि, नीचे दिए गए सेक्शन में बताए गए तरीके से, ग्रुप को खुद भी तय किया जा सकता है. हमारा सुझाव है कि आप किसी मौजूदा ग्रुप का इस्तेमाल करें. इससे, उपयोगकर्ता को अनुमति का यूज़र इंटरफ़ेस (यूआई) आसानी से दिखता है.

आपको अनुमति के लिए, लेबल और जानकारी, दोनों देनी होगी. ये स्ट्रिंग रिसॉर्स होते हैं, जिन्हें उपयोगकर्ता तब देख सकता है, जब वह अनुमतियों की सूची (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>
मेनिफ़ेस्ट टैग के लिए एपीआई रेफ़रंस, जो आपके ऐप्लिकेशन के लिए ज़रूरी सिस्टम अनुमतियों का एलान करता है.

शायद आपकी दिलचस्पी इनमें भी हो:

Android की सुरक्षा के बारे में खास जानकारी
Android प्लैटफ़ॉर्म के सुरक्षा मॉडल के बारे में पूरी जानकारी.