Repository navigation
feat(policy): enforce server client policies on Android - #32
Merged
Merged
Conversation
added 2 commits
October 2, 2026 20:43
- ClientPolicy (core/common): parsing with unrestricted fallbacks, allowed split modes, forced auto-connect, always-on, JSON for the cache. - ClientPolicyRepository (core/data): last known policy in DataStore (applies offline; never fetched = no restriction). - ApiClient: GET /api/v1/client/policy with If-None-Match (304), policyVersion on heartbeat and permissions answers. - ClientPolicyManager: refresh on app start, on a new policyVersion (heartbeat / permissions), reset after a server change; forces the auto-connect setting and clamps a disallowed split-tunnel mode. - Enforcement: boot auto-connect follows the policy, required/always-on connect on app start (VPN consent needed), always-on refuses the in-app and tile disconnect, TunnelConnector clamps the split mode (locked server preset keeps priority), settings/split-tunnel/server screens show locked controls with "Vom Administrator festgelegt", server change and config import hidden under lockServer. - Android limits: the app cannot turn on system Always-on VPN or "Block connections without VPN"; a prominent card with a button to the system VPN settings is shown when the policy requires a kill switch/always-on. Documented in the README (not a security boundary). - de/en strings, unit tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016xX1efcZF1f6G9rhmaJNLD
Brings in the support bundle feature. Conflicts resolved by keeping both sides: heartbeat answer (policyVersion + support request), API models and imports, SettingsViewModel (support collector/uploader + client policy manager), strings and tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016xX1efcZF1f6G9rhmaJNLD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Android part of Client-Richtlinien vom Server (server: CallMeTechie/gatecontrol#256).
What
ClientPolicy(core/common): parsing with per-field unrestricted fallbacks, allowed split modes, forced auto-connect, always-on, JSON for the cache.ClientPolicyRepository(core/data): the last known policy lives in DataStore, so it applies offline. A policy that was never fetched means no restriction.ApiClient.getClientPolicy(If-None-Match)→ 304 handling.policyVersionon the heartbeat and permissions answers.ClientPolicyManager:policyVersion(heartbeat/permissions), and after a server change (reset)Enforcement
requiredalways_onrequired/forbiddenTunnelConnectorclamps the mode (full tunnel if allowed). A locked server preset keeps priority (existingadminLocked)Locked controls show "Vom Administrator festgelegt" / "Set by your administrator". Settings shows a "managed" banner.
Android limits
An app cannot switch on the system Always-on VPN or "Block connections without VPN". When the policy requires a kill switch or always-on, the app shows a prominent card with a button to the system VPN settings, on the VPN screen and in Settings. Enrollment through an external setup link is still possible under lockServer, because it needs a fresh admin setup code. Documented in the README, together with the note that the policy is not a security boundary against the device owner.
Tests
./gradlew testDebugUnitTest lintDebug assembleDebug: green locally, 421 unit tests including new ones:ClientPolicyTestClientPolicyManagerTest: fetch/304/offline/version hint/reset🤖 Generated with Claude Code
https://claude.ai/code/session_016xX1efcZF1f6G9rhmaJNLD
Generated by Claude Code