Navigate back to the homepage

GitHub Actions - Detect silently added permissions part-1

Dion Segijn
April 20th, 2020 · 2 min read

Unwanted permissions

At Temper we’ve had cases where we were releasing our app and the Play Store gave warnings that it detected new permissions being added to our app bundle which we didn’t add ourselves. After some investigation we found out that new permissions were added to one of the dependencies that was updated.

I started exploring if I can get notified automatically with Github Actions when a dependency add a new permission in their latest release. The plan was to write a Workflow that builds an APK in two parallel jobs of your main branch and the branch of which the dependency was updated. Then find out what permissions each APK require and compare both results. To finish it off, the workflow should notify us by commenting on the pull request if any changes in permissions are detected.

The image below illustrates each step required to do so in the workflow

Workflow detecting new permissions

If a dependency silently adds a permission to their manifest and we update the dependency to that new version in a pull request, we will get a message like this:

PR comment with permissions detected

Below I’m going to explain each job of this workflow, if you want to go ahead and check the workflow already, you can find it here

The Workflow

Let’s start with the first job in the workflow named build-develop. This job is highlighted in the image below and contains 4 steps. The following steps in this job are quite straightforward if you’re familiar with Github Actions. If you never worked with Github actions before, I wrote an introduction about it here.

Workflow detecting new permissions
1name: Check permissions
2
3on:
4 pull_request:
5 paths:
6 - '**/dependencies.gradle'
7
8jobs:
9 build-develop:
10 runs-on: ubuntu-latest
11 steps:
12 - uses: actions/checkout@v2
13 with:
14 ref: develop
15
16 - name: Build develop APK
17 run: ./gradlew app:assembleDebug
18
19 - name: Get permissions
20 run: $ANDROID_HOME/build-tools/29.0.3/aapt d permissions app/build/outputs/apk/debug/app-debug.apk > permissions-develop.txt
21
22 - name: Upload permissions file develop
23 uses: actions/upload-artifact@v1
24 with:
25 name: permissions
26 path: permissions-develop.txt
  • First we check out the development branch
  • Then we run ./gradlew app:assembleDebug to build a debug apk
  • Then we extract a list of permissions from the apk with aapt. I’ll tell more about this tool later. This list is written to permissions-develop.txt.
  • In the last step permissions-develop.txt is uploaded to the artifacts folder. This so we can use this file in the last job of this workflow.

Every file uploaded to the artifacts folder can be shared with other jobs in the same workflow.

Extracting permissions from .apk files

Aapt is the Android Asset Packaging tool providing all sorts of tooling around .apk files. We use it in this case to extract a list of permissions that an apk requires. When running aapt on an .apk file you’ll get the following output:

:> aapt d permissions {your_app.apk}

1package: com.example.yourpackagename
2uses-permission: name='android.permission.INTERNET'
3uses-permission: name='android.permission.ACCESS_NETWORK_STATE'
4uses-permission: name='android.permission.ACCESS_WIFI_STATE'
5uses-permission: name='android.permission.CAMERA'
6uses-permission: name='android.permission.ACCESS_FINE_LOCATION'
7uses-permission: name='android.permission.VIBRATE'

Running the second job in parallel

Each job defined in a workflow will run in parallel unless told otherwise. For example, the third job in this workflow waits until the first two jobs succeed. More about this in the second part of this series.

Previously I talked about the steps in the build-develop job. We want to run another job exactly like that but with minimal changes. Instead of using the development branch we will use the current branch in which a dependency has been updated.

Since we follow the same steps I’ll skip how that is being done, but you can see it implemented here

Two jobs running in parallel

That’s it for this article. In the next one I’ll go more in depth on how to retrieve the files we just uploaded to the artifacts folder of this workflow and how to utilise the diff tool to detect any changes and post them to the Pull Request on GitHub. Read more about that in the second part here

In the meantime, follow me on twitter @DionSegijn if you have any questions

More articles from Dion Segijn

Konfetti - Simple 3D animation on a 2D Android canvas

Implementing a 3D rotation effect on a 2D canvas on Android might be easier than you think. This article demonstrates the three things you need in order to achieve that.

October 22nd, 2020 · 2 min read

GitHub Actions - Detect silently added permissions part-2

In the second part we continue with the extracted permissions and use diff to detect any changes. The results will be posted to the Pull Request.

April 29th, 2020 · 2 min read
© 2020–2021 Dion Segijn
Link to $https://twitter.com/DionSegijnLink to $https://github.com/DanielMartinusLink to $https://www.linkedin.com/in/dionsegijn/Link to $https://www.instagram.com/dionsegijn/