SEC-1: build-inject Google Maps Android key; remove leaked literal
Removes the leaked Google Maps API key literal from README.md and the
live com.google.android.geo.API_KEY in AndroidManifest.xml (which shipped
in every built APK). The manifest value is now the build-time placeholder
${MAPS_API_KEY}, injected via AndroidManifestPlaceholders from the
MapsApiKey MSBuild property, resolved from a CI secret (-p:MapsApiKey=),
the MAPS_API_KEY env var, or a gitignored maps.key.props at the repo root
(maps.key.props.example committed as the template). maps.key.props is
gitignored so a real key is never committed.
No rotated key is included here; the human supplies it via CI secret.
Pairs with the console key rotation to close SEC-1 (decisions.md
2026-08-20; security/sec-1-gmaps-key.md). Git history intentionally not
rewritten (recorded risk-acceptance relies on revocation of the old key).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -482,3 +482,6 @@ $RECYCLE.BIN/
|
|||||||
|
|
||||||
# Vim temporary swap files
|
# Vim temporary swap files
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
|
# SEC-1: local Google Maps key injection — never commit the real key
|
||||||
|
maps.key.props
|
||||||
|
|||||||
@@ -46,6 +46,18 @@
|
|||||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- SEC-1: the Google Maps Android key is injected at build time, never committed.
|
||||||
|
Resolution order: (1) MapsApiKey MSBuild property (pass -p:MapsApiKey=... in CI from a
|
||||||
|
secret), else (2) the MAPS_API_KEY environment variable, else (3) a gitignored
|
||||||
|
maps.key.props at the repo root (copy maps.key.props.example). Left empty for local
|
||||||
|
builds without a key — maps stay blank; the build does not embed a literal. -->
|
||||||
|
<Import Project="$(MSBuildThisFileDirectory)..\maps.key.props"
|
||||||
|
Condition="Exists('$(MSBuildThisFileDirectory)..\maps.key.props')" />
|
||||||
|
<PropertyGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">
|
||||||
|
<MapsApiKey Condition="'$(MapsApiKey)' == ''">$(MAPS_API_KEY)</MapsApiKey>
|
||||||
|
<AndroidManifestPlaceholders>MAPS_API_KEY=$(MapsApiKey)</AndroidManifestPlaceholders>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- App Icon -->
|
<!-- App Icon -->
|
||||||
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
|
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">
|
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">
|
||||||
<!-- Google Maps API key: replace with your key from https://console.cloud.google.com (Maps SDK for Android) -->
|
<!-- Google Maps API key is injected at build time from the MAPS_API_KEY MSBuild
|
||||||
<meta-data android:name="com.google.android.geo.API_KEY" android:value="AIzaSyDhH16gF-7UN-CBsTQGfQSHNGjLC6VJ5dI" />
|
placeholder (see FieldLogger.csproj / maps.key.props.example). Never commit a key
|
||||||
|
literal here — SEC-1. -->
|
||||||
|
<meta-data android:name="com.google.android.geo.API_KEY" android:value="${MAPS_API_KEY}" />
|
||||||
</application>
|
</application>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -4,8 +4,6 @@ Cross-platform .NET MAUI app (Windows, macOS, iOS, Android) for logging utility
|
|||||||
points from an **Underground Magnetics locating receiver** paired with RTK GPS positions
|
points from an **Underground Magnetics locating receiver** paired with RTK GPS positions
|
||||||
from a **Maglink (H11) RTK receiver**, both over BLE.
|
from a **Maglink (H11) RTK receiver**, both over BLE.
|
||||||
|
|
||||||
Maps API Key: AIzaSyDhH16gF-7UN-CBsTQGfQSHNGjLC6VJ5dI
|
|
||||||
|
|
||||||
## Solution layout
|
## Solution layout
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -40,8 +38,13 @@ doc/ Device protocol documentation
|
|||||||
|
|
||||||
## Setup required before running
|
## Setup required before running
|
||||||
|
|
||||||
1. **Google Maps key (Android):** replace `YOUR_GOOGLE_MAPS_ANDROID_API_KEY` in
|
1. **Google Maps key (Android):** the manifest key is **injected at build time**, never
|
||||||
`FieldLogger/Platforms/Android/AndroidManifest.xml` (Google Cloud Console → Maps SDK for Android).
|
committed (SEC-1). Provide it one of three ways: pass `-p:MapsApiKey=<key>` to
|
||||||
|
`dotnet build` (how CI supplies it from a secret), set the `MAPS_API_KEY` environment
|
||||||
|
variable, or copy `maps.key.props.example` to `maps.key.props` (gitignored) at the repo
|
||||||
|
root and put your key there. Use a key restricted to the app package + release SHA-1
|
||||||
|
(Google Cloud Console → Maps SDK for Android). Without a key, maps render blank but the
|
||||||
|
app builds.
|
||||||
2. **Google Maps key (Windows):** create a Maps JavaScript API key and paste it into the
|
2. **Google Maps key (Windows):** create a Maps JavaScript API key and paste it into the
|
||||||
Settings page of the app.
|
Settings page of the app.
|
||||||
3. **Maglink GATT UUIDs:** the Maglink docs describe the serial protocol but not its GATT
|
3. **Maglink GATT UUIDs:** the Maglink docs describe the serial protocol but not its GATT
|
||||||
|
|||||||
13
maps.key.props.example
Normal file
13
maps.key.props.example
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!--
|
||||||
|
SEC-1: local Google Maps key injection for Android builds.
|
||||||
|
|
||||||
|
Copy this file to `maps.key.props` (same directory) and paste your restricted key.
|
||||||
|
`maps.key.props` is gitignored — never commit a real key. CI supplies the key instead
|
||||||
|
via `-p:MapsApiKey=$SECRET` or the MAPS_API_KEY environment variable, so this file is
|
||||||
|
only for local development.
|
||||||
|
-->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<MapsApiKey>YOUR_GOOGLE_MAPS_ANDROID_API_KEY</MapsApiKey>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
Reference in New Issue
Block a user