RepoPilotOpen in app →

beemdevelopment/Aegis

A free, secure and open source app for Android to manage your 2-step verification tokens.

Mixed

Mixed signals — read the receipts

weakest axis
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility; no tests detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2mo ago
  • 8 active contributors
  • GPL-3.0 licensed
Show all 7 evidence items →
  • CI configured
  • Concentrated ownership — top contributor handles 53% of recent commits
  • GPL-3.0 is copyleft — check downstream compatibility
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: relicense under MIT/Apache-2.0 (rare for established libs)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/beemdevelopment/aegis?axis=fork)](https://repopilot.app/r/beemdevelopment/aegis)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/beemdevelopment/aegis on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: beemdevelopment/Aegis

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/beemdevelopment/Aegis shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Mixed signals — read the receipts

  • Last commit 2mo ago
  • 8 active contributors
  • GPL-3.0 licensed
  • CI configured
  • ⚠ Concentrated ownership — top contributor handles 53% of recent commits
  • ⚠ GPL-3.0 is copyleft — check downstream compatibility
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live beemdevelopment/Aegis repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/beemdevelopment/Aegis.

What it runs against: a local clone of beemdevelopment/Aegis — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in beemdevelopment/Aegis | Confirms the artifact applies here, not a fork | | 2 | License is still GPL-3.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 102 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>beemdevelopment/Aegis</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of beemdevelopment/Aegis. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/beemdevelopment/Aegis.git
#   cd Aegis
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of beemdevelopment/Aegis and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "beemdevelopment/Aegis(\\.git)?\\b" \\
  && ok "origin remote is beemdevelopment/Aegis" \\
  || miss "origin remote is not beemdevelopment/Aegis (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
  && ok "license is GPL-3.0" \\
  || miss "license drift — was GPL-3.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java" \\
  && ok "app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java" \\
  || miss "missing critical file: app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java"
test -f "app/src/main/java/com/beemdevelopment/aegis/database/AppDatabase.java" \\
  && ok "app/src/main/java/com/beemdevelopment/aegis/database/AppDatabase.java" \\
  || miss "missing critical file: app/src/main/java/com/beemdevelopment/aegis/database/AppDatabase.java"
test -f "app/src/main/java/com/beemdevelopment/aegis/crypto/MasterKey.java" \\
  && ok "app/src/main/java/com/beemdevelopment/aegis/crypto/MasterKey.java" \\
  || miss "missing critical file: app/src/main/java/com/beemdevelopment/aegis/crypto/MasterKey.java"
test -f "app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java" \\
  && ok "app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java" \\
  || miss "missing critical file: app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java"
test -f "app/src/main/java/com/beemdevelopment/aegis/Preferences.java" \\
  && ok "app/src/main/java/com/beemdevelopment/aegis/Preferences.java" \\
  || miss "missing critical file: app/src/main/java/com/beemdevelopment/aegis/Preferences.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 102 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~72d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/beemdevelopment/Aegis"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Aegis Authenticator is a free, open-source Android app (Java, 1.1M LOC) that securely stores and manages 2FA/2SV tokens using HOTP and TOTP algorithms. It encrypts the vault with AES-256-GCM, supports biometric and password unlocking via scrypt, and can import from 9+ authenticator apps including Google Authenticator, Authy, and Microsoft Authenticator. Standard Android monolith: app/src/main contains Activities and Fragments, app/src/androidTest holds instrumented tests, app/schemas/ stores Room database versions (1.json), app/config/ houses library configs and licenses (Krop, libsu, TextDrawable, TrustedIntents). Vault encryption/decryption logic centralizes in VaultRepository, with entry import filters for each service (Google, Authy, 2FAS, etc).

👥Who it's for

Android users who need a security-hardened replacement for Google Authenticator or other 2FA apps; also privacy-conscious users who want a fully open-source, locally-stored vault without cloud dependency. Contributors should have Android/Java experience and interest in cryptography or 2FA workflows.

🌱Maturity & risk

Actively maintained and production-ready: at version 3.4.2 (versionCode 81) with CI/CD via GitHub Actions (build-app-workflow.yaml, codeql-analysis.yml), comprehensive instrumented tests (VaultRepositoryTest, BackupExportTest, IntroTest), ProGuard obfuscation, and Room database schemas versioned. Crowdin integration shows active localization (27 languages+).

Low risk for a mature security app: single package namespace (com.beemdevelopment.aegis) with clear separation of concerns, Dagger Hilt DI for testability, and androidx dependencies only. Main risks are: cryptographic correctness requires careful auditing (AES-256-GCM + scrypt), minSdkVersion 23 (Android 6.0+) may exclude older devices, and small team (beemdevelopment org) means slower response to vulns.

Active areas of work

Active development on 2FA token management: GitHub Workflows run CodeQL security scans, Crowdin handles translation sync, build automation targets SDK 35 with multiDexEnabled for method count. No PR/issue data in file list, but test suite (OverallTest, PanicTriggerTest, DeepLinkTest) suggests recent work on panic-lock, deep linking, and vault integrity.

🚀Get running

Clone and build with Gradle: git clone https://github.com/beemdevelopment/Aegis.git && cd Aegis && ./gradlew assembleDebug. Requires Android SDK 35, Java 11+, Git for hash/branch injection via getCmdOutput tasks. Emulator or device with API 23+ to run app/src/androidTest tests via ./gradlew connectedAndroidTest.

Daily commands: ./gradlew installDebug to deploy to device/emulator, or ./gradlew run via Android Gradle plugin. For testing: ./gradlew connectedAndroidTest runs instrumented tests with ANDROIDX_TEST_ORCHESTRATOR. Debug APK loads from app/src/debug with separate FileProvider authority (*.debug.fileprovider).

🗺️Map of the codebase

  • app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java — Main application entry point; initializes Dagger Hilt, theme configuration, and all core app infrastructure.
  • app/src/main/java/com/beemdevelopment/aegis/database/AppDatabase.java — Room database schema definition; contains all persistent data models for vault entries, audit logs, and settings.
  • app/src/main/java/com/beemdevelopment/aegis/crypto/MasterKey.java — Cryptographic key management for vault encryption; handles SCrypt derivation and encrypted storage in Android Keystore.
  • app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java — Abstract base class for all OTP implementations (TOTP, HOTP, MOTP, YAOTP); core token generation logic.
  • app/src/main/java/com/beemdevelopment/aegis/Preferences.java — Centralized SharedPreferences wrapper for all user settings, themes, sorting, and security policies.
  • app/build.gradle — Build configuration with Gradle plugins (Hilt, Protobuf, aboutLibraries), dependencies, and SDK targets.

🛠️How to make changes

Add a new OTP algorithm variant

  1. Create new class extending OTP abstract base in app/src/main/java/com/beemdevelopment/aegis/crypto/otp/ (app/src/main/java/com/beemdevelopment/aegis/crypto/otp/OTP.java)
  2. Implement generateCodeAtTime(long timestamp) following RFC spec (e.g., RFC 6238 for TOTP) ([your-new-otp-class].java)
  3. Register in vault entry model as a supported OTP type enum (app/src/main/java/com/beemdevelopment/aegis/database/AppDatabase.java)
  4. Add unit tests in app/src/androidTest/java/com/beemdevelopment/aegis/ to validate token generation against test vectors (app/src/androidTest/java/com/beemdevelopment/aegis/OverallTest.java)

Add a new user preference setting

  1. Add SharedPreferences key and getter/setter method to the Preferences facade (app/src/main/java/com/beemdevelopment/aegis/Preferences.java)
  2. Create UI preference control in settings Activity/Fragment (RecyclerView item or PreferenceFragmentCompat binding) ([settings-activity-or-fragment].java)
  3. Read preference in relevant UI or service component to apply behavior (e.g., theme application in AegisApplication) (app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java)
  4. If security-related, document in security design; if UI-related, add to Theme or ViewMode enums if applicable (app/src/main/java/com/beemdevelopment/aegis/Theme.java)

Add a new backup/export format

  1. Implement serializer/deserializer class alongside existing encrypted JSON logic (app/src/androidTest/resources/com/beemdevelopment/aegis/aegis_encrypted.json)
  2. Update BackupExportTest to validate round-trip (encrypt → save → load → decrypt → verify entries) (app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java)
  3. Register format in export/import UI flow and backup repository (app/src/main/java/com/beemdevelopment/aegis/database/AppDatabase.java)
  4. Test with VaultRepositoryTest to ensure vault integrity and cryptographic correctness (app/src/androidTest/java/com/beemdevelopment/aegis/VaultRepositoryTest.java)

Add a new security feature (e.g., password hashing policy)

  1. Create parameter class analogous to SCryptParameters with configuration fields (cost, parallelism, salt length) (app/src/main/java/com/beemdevelopment/aegis/crypto/SCryptParameters.java)
  2. Add logic in MasterKey to use new parameters during key derivation (app/src/main/java/com/beemdevelopment/aegis/crypto/MasterKey.java)
  3. Store configuration in vault metadata (AppDatabase schema) for versioning and migration (app/src/main/java/com/beemdevelopment/aegis/database/AppDatabase.java)
  4. Add Preferences toggle for users to opt-in and test with AegisTestApplication and cryptographic unit tests (app/src/main/java/com/beemdevelopment/aegis/Preferences.java)

🪤Traps & gotchas

No build-time secrets (.env) visible, but Git hash/branch injection via getCmdOutput (lines in build.gradle) requires Git binary in PATH. Instrumented tests use ANDROIDX_TEST_ORCHESTRATOR (testOptions → execution 'ANDROIDX_TEST_ORCHESTRATOR'), which clears package data between test runs—don't rely on test state persistence. Room schema history (schemas/) is auto-generated; manually editing causes build failures. compileSdk 35 requires Android Gradle Plugin 8.1+; older AGP versions will fail.

🏗️Architecture

💡Concepts to learn

  • AES-256-GCM (Galois/Counter Mode) — Aegis encrypts the entire vault with AES-256-GCM; understanding authenticated encryption (both confidentiality and integrity) is critical for reviewing or modifying vault security
  • Scrypt (key derivation function) — User password → encryption key via scrypt (not PBKDF2); scrypt's memory-hard design resists brute-force attacks on weak passwords — essential for security audits
  • TOTP (Time-based One-Time Password) and HOTP (HMAC-based One-Time Password) — Aegis generates RFC 6238 (TOTP) and RFC 4226 (HOTP) tokens; understanding the algorithms ensures correct import/generation and helps debug compatibility issues
  • Android Keystore (Biometric unlock) — Aegis stores encryption keys in Android Keystore for biometric unlock; this hardware-backed key management is critical for understanding security boundaries on rooted devices
  • Room Database + Schema Versioning — Vault persistence uses Room with versioned schemas (app/schemas/); understanding Room migrations ensures safe addition of new token fields without data loss
  • Dagger Hilt (Dependency Injection) — App uses Hilt for DI (dagger.hilt.android.plugin); essential for understanding testability patterns and component scoping (e.g., vault repository singleton)
  • Protocol Buffers (protobuf) — build.gradle applies com.google.protobuf plugin; vault format may use protobuf for compact serialization; relevant for schema changes and import compatibility
  • google/authenticator — Official Google Authenticator open-source reference; Aegis is a security-hardened fork with vault encryption and backup features Google Authenticator lacks
  • bitwarden/mobile — Bitwarden Mobile (Android) shares vault encryption patterns (AES-GCM, scrypt key derivation) and backup workflows; reference for Kotlin/MVVM modernization
  • andOTP/andOTP — andOTP is a direct competitor in the open-source 2FA space; Aegis can import andOTP vaults (app/src/main/java/.../vectors/)
  • Gargron/Authenticator — Another TOTP authenticator with Room persistence; useful reference for Material Design 3 migration and Fragment-based UI patterns
  • beemdevelopment/Aegis-web — Companion project (if exists) for web vault preview/export tools; extends Aegis ecosystem beyond mobile

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for VaultRepository encryption/decryption

VaultRepositoryTest.java exists but likely needs expanded coverage for edge cases in the encryption pipeline. The vault is the core security component, and given the emphasis on 'secure encryption' in the README, rigorous unit tests for encryption/decryption flows, key derivation, and error handling would significantly reduce security regressions. This directly supports the app's core value proposition.

  • [ ] Review app/src/androidTest/java/com/beemdevelopment/aegis/vault/VaultRepositoryTest.java to identify gaps in encryption test coverage
  • [ ] Add unit tests for invalid key scenarios, corrupted vault files, and migration between encryption schemes
  • [ ] Add tests for backup/restore encryption workflows using the test vectors in app/src/androidTest/java/com/beemdevelopment/aegis/vectors/VaultEntries.java
  • [ ] Verify coverage of app/src/main/java/com/beemdevelopment/aegis vault-related classes

Add GitHub Actions workflow for automated security vulnerability scanning on dependencies

The repo has build and CodeQL workflows (.github/workflows/build-app-workflow.yaml, codeql-analysis.yml) but lacks automated dependency scanning. For a security-focused 2FA app with many Android/Java dependencies (Dagger, Room, Protobuf, etc.), a Dependabot or OWASP dependency-check workflow would catch known CVEs early and match the security-first positioning.

  • [ ] Create .github/workflows/dependency-check.yml using OWASP dependency-check or Dependabot configuration
  • [ ] Configure it to scan app/build.gradle and report vulnerabilities on PRs
  • [ ] Set up automated alerts for high-severity CVEs in transitive dependencies
  • [ ] Document the process in CONTRIBUTING.md for maintainers

Add integration tests for deep link and backup export flows end-to-end

DeepLinkTest.java and BackupExportTest.java exist but are likely shallow. Deep link handling and backup export are critical user-facing features for onboarding and data portability. Comprehensive integration tests covering malformed deep links, backup encryption during export, and format compatibility would catch regressions that break core workflows.

  • [ ] Expand app/src/androidTest/java/com/beemdevelopment/aegis/DeepLinkTest.java with test cases for invalid otpauth:// URIs, edge cases in parameters, and conflict scenarios
  • [ ] Expand app/src/androidTest/java/com/beemdevelopment/aegis/BackupExportTest.java to cover encrypted vs. plaintext export, format validation (aegis_encrypted.json/aegis_plain.json), and re-import verification
  • [ ] Add tests using the sample vaults in app/src/androidTest/resources/com/beemdevelopment/aegis/ to ensure round-trip consistency
  • [ ] Integrate results with the existing ANDROIDX_TEST_ORCHESTRATOR setup in build.gradle

🌿Good first issues

  • Add unit tests for entry import filters: app/src/main/java lacks visible import adapter tests; replicate VaultRepositoryTest patterns for each service (GoogleAuthenticator, Authy, 2FAS, etc.) to ensure robustness.
  • Expand vault.md documentation with code examples: docs/vault.md describes encryption design but lacks concrete AES-256-GCM/scrypt usage examples; add snippets showing key derivation and encryption flow.
  • Implement missing locale strings for new themes: Crowdin reports partial localization; complete translations for Light/Dark/AMOLED theme strings in app/src/main/res/values-*/strings.xml for underrepresented languages.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 59d5c64 — Release v3.4.2 (michaelschattgen)
  • 6ca5e94 — Update translations from Crowdin (michaelschattgen)
  • d2ebda7 — Merge pull request #1774 from WAPEETY/master (michaelschattgen)
  • 7071b5e — Inverted buttons position in dialog_select_groups (WAPEETY)
  • 7cbdeca — Merge pull request #1766 from michaelschattgen/feature/otpauth-uri-add (alexbakker)
  • 170cd93 — Add ability to import otpauth uri from clipboard (michaelschattgen)
  • b5e21a5 — Merge pull request #1763 from michaelschattgen/fix/auto-complete-secret (alexbakker)
  • 2edd388 — Merge pull request #1762 from michaelschattgen/fix/tile-padding (alexbakker)
  • 1607132 — Merge pull request #1761 from michaelschattgen/fix/quicksettings-tile (alexbakker)
  • 41fad61 — Use custom NoAutofill field to avoid password manager issues (michaelschattgen)

🔒Security observations

The Aegis Authenticator codebase demonstrates strong security practices with encryption-focused design (crypto module present, vault repository pattern), proper use of Android security frameworks (KeyStore, MasterKey), and comprehensive test coverage. However, minor concerns exist around build-time information exposure (Git hashes) and incomplete configuration code. The project shows good security discipline with security-relevant directories for cryptography and vault management. Recommendations focus on removing unnecessary build-time information disclosure and completing test configuration. No critical vulnerabilities related to hardcoded secrets, SQL injection, or dangerous patterns were identified in the provided file structure.

  • Medium · Git Information Exposed in Build Config — app/build.gradle - buildConfigField for GIT_HASH and GIT_BRANCH. Build configuration exposes Git commit hash and branch name as buildConfigField. This information is compiled into the APK and can be extracted, potentially revealing development details and commit history to attackers. Fix: Remove or conditionally include git information only in debug builds. Use BuildConfig.DEBUG to gate this sensitive information: buildConfigField "String", "GIT_HASH", "${BuildConfig.DEBUG ? \"${getGitHash()}\" : \"\"}"
  • Medium · Incomplete Test Configuration Code — app/build.gradle - testOptions.unitTests configuration. The build.gradle file appears to have truncated/incomplete code in the testOptions section (showStackTr cut off). This could indicate incomplete configuration or potential build issues that might mask security problems. Fix: Complete the test configuration and ensure all test options are properly defined. Verify the full file is present and syntactically correct.
  • Low · MultiDex Enabled — app/build.gradle - defaultConfig.multiDexEnabled. multiDexEnabled is set to true, which is necessary for larger APKs but increases app complexity. While not a direct vulnerability, it can complicate security analysis and increase attack surface. Fix: Keep MultiDex enabled if necessary for app size, but ensure all dependencies are regularly audited. Consider using ProGuard/R8 rules (noted in app/proguard-rules.pro) to minimize method counts.
  • Low · Test Instrumentation Runner Arguments — app/build.gradle - testInstrumentationRunnerArguments. Test instrumentation runner is configured with clearPackageData set to 'true'. While useful for testing, ensure sensitive test data cleanup procedures are properly implemented. Fix: Verify that ANDROIDX_TEST_ORCHESTRATOR properly cleans up all sensitive test data between test runs. Review test setup in AegisTestRunner.java.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · beemdevelopment/Aegis — RepoPilot