BYOD Certificate Enrollment with HashiCorp Vault

Issue client certificates for iOS and Android devices using HashiCorp Vault PKI for 802.1X EAP-TLS authentication.

Overview

This guide covers manual certificate enrollment for BYOD (Bring Your Own Device) scenarios where mobile devices need 802.1X authentication to the Domus-Secure SSID.

Design Philosophy: Start with manual enrollment to validate the workflow, then automate with a REST API wrapper or ISE native integration later.

Prerequisites

  • HashiCorp Vault running on certmgr-01 (unsealed and authenticated)

  • Vault PKI engine configured with domus-byod role (90-day TTL)

  • Device information: hostname, owner, platform (iOS/Android)

  • Secure method to transfer PKCS#12 bundle to device

Certificate Issuance Workflow

Step 1: Prepare Vault Environment

SSH to certmgr-01 and set Vault environment variables:

# SSH to certificate manager
ssh certmgr-01

# Set Vault connection (HTTP, localhost-only)
export VAULT_ADDR='http://127.0.0.1:8200'

# Authenticate to Vault (retrieve token from dsec)
export VAULT_TOKEN="<your-vault-token>"

# Verify Vault status
vault status

Vault runs on HTTP (not HTTPS) bound to 127.0.0.1:8200. If you see http: server gave HTTP response to HTTPS client, you forgot to set VAULT_ADDR.

Step 2: Issue Certificate for Mobile Device

Choose a naming convention for device certificates:

Table 1. Device Certificate Naming Convention
Platform Hostname Format Common Name Example

Android

<device-model>-<owner>.byod.inside.domusdigitalis.dev

zfold7-evanusmodestus.byod.inside.domusdigitalis.dev

iOS

<device-model>-<owner>.byod.inside.domusdigitalis.dev

iphone16-evanusmodestus.byod.inside.domusdigitalis.dev

Example: Android Device (Samsung Z Fold 7)

# Create working directory
mkdir -p ~/byod-certs/zfold7
cd ~/byod-certs/zfold7

# Issue certificate from Vault (90-day TTL)
vault write -format=json pki_int/issue/domus-byod \
  common_name="zfold7-evanusmodestus.byod.inside.domusdigitalis.dev" \
  ttl=2160h > zfold7-cert.json

# Verify issuance
jq -r '.data.common_name' zfold7-cert.json
jq -r '.data.expiration' zfold7-cert.json | xargs -I {} date -d @{}
Expected Output
{
  "request_id": "...",
  "data": {
    "certificate": "-----BEGIN CERTIFICATE-----\n...",
    "private_key": "-----BEGIN RSA PRIVATE KEY-----\n...",
    "ca_chain": ["-----BEGIN CERTIFICATE-----\n..."],
    "common_name": "zfold7-evanusmodestus.byod.inside.domusdigitalis.dev",
    "expiration": 1735689600,
    "issuing_ca": "-----BEGIN CERTIFICATE-----\n...",
    "serial_number": "..."
  }
}

Step 3: Extract to PKCS#12 Format

Mobile devices (iOS/Android) require PKCS#12 (.p12) format containing:

  • Client certificate

  • Private key

  • CA chain (DOMUS-ISSUING-CA + DOMUS-ROOT-CA)

# Extract certificate components
jq -r '.data.certificate' zfold7-cert.json > cert.pem
jq -r '.data.private_key' zfold7-cert.json > key.pem
jq -r '.data.ca_chain[]' zfold7-cert.json > ca.pem

# Create PKCS#12 bundle (will prompt for export password)
openssl pkcs12 -export \
  -out zfold7-evanusmodestus.p12 \
  -inkey key.pem \
  -in cert.pem \
  -certfile ca.pem \
  -name "Domus BYOD - Z Fold 7"

# Verify PKCS#12 contents (will prompt for password)
openssl pkcs12 -info -in zfold7-evanusmodestus.p12 -nokeys

Export Password Security

  • Choose a strong temporary password (user will enter during import)

  • Communicate password out-of-band (not with the .p12 file)

  • Password is ONLY for PKCS#12 encryption, not the private key passphrase

Step 4: Secure Cleanup

# Securely delete intermediate files (keep only .p12)
shred -u key.pem cert.pem ca.pem zfold7-cert.json

# Verify only PKCS#12 remains
ls -lh
# Expected: zfold7-evanusmodestus.p12

Certificate Transfer Methods

Deploy a simple HTTPS portal on certmgr-01 where users can:

  1. Authenticate with AD credentials

  2. Download their device-specific PKCS#12 bundle

  3. Receive export password via separate channel (SMS/email)

Future Enhancement: This will be automated with ISE BYOD portal integration + Vault REST API wrapper.

Option 2: Secure File Transfer

For manual/lab testing:

# SCP to user's workstation
scp zfold7-evanusmodestus.p12 modestus-razer:~/Downloads/

# From workstation, transfer to device via:
# - AirDrop (iOS)
# - USB/MTP transfer (Android)
# - Encrypted email (less ideal)

Option 3: USB Direct Transfer

For maximum security:

  1. Copy .p12 to USB drive from certmgr-01

  2. Physically transfer USB to device location

  3. Import directly via USB-C/Lightning

Device Import Procedures

Android Import

Tested on Samsung Z Fold 7 running Android 15 with One UI 7.0

Android Certificate Import Steps
  1. Transfer zfold7-evanusmodestus.p12 to device storage

  2. Settings → Security → Credential Storage → Install from device storage

  3. Navigate to .p12 file location

  4. Enter PKCS#12 export password

  5. Name the certificate: "Domus BYOD - Z Fold 7"

  6. Select "VPN and apps" usage

  7. Verify import: Settings → Security → Trusted credentials → User

iOS Import

iOS Certificate Import Steps
  1. AirDrop iphone16-evanusmodestus.p12 to iPhone

  2. Tap notification → "Profile Downloaded"

  3. Settings → General → VPN & Device Management

  4. Tap profile → Install

  5. Enter device passcode

  6. Enter PKCS#12 export password

  7. Verify: Settings → General → About → Certificate Trust Settings

Verification

Verify Certificate on Device

Android Verification

# Via ADB (if device connected)
adb shell ls /data/misc/user/0/cacerts-added/

# Expected: Certificate file with hash name

iOS Verification

Settings → General → About → Certificate Trust Settings

  • Should show "Domus BYOD - <device>" under "Enable Full Trust for Root Certificates"

  • Manually enable trust for DOMUS-ROOT-CA

Verify Certificate Details

Use device browser to visit: certmgr-01.inside.domusdigitalis.dev/verify

Expected certificate details:

  • Issued To: zfold7-evanusmodestus.byod.inside.domusdigitalis.dev

  • Issued By: DOMUS-ISSUING-CA

  • Valid Until: ~90 days from issuance

  • Key Usage: Client Authentication

Certificate Lifecycle

Table 2. BYOD Certificate Lifecycle
Stage Duration Action

Issuance

Day 0

Vault issues cert via domus-byod role

Active Use

Days 1-80

Device authenticates to 802.1X via EAP-TLS

Renewal Window

Days 81-90

User receives notification to renew (future automation)

Expiration

Day 90

Certificate expires, device loses network access

Revocation (if needed)

Any time

Admin revokes cert, device immediately blocked

Troubleshooting

Certificate Not Appearing on Device

Android:

  • Check file location (must be in accessible storage, not system partition)

  • Verify .p12 format: file zfold7-evanusmodestus.p12 should show "data"

  • Try renaming to .pfx extension

iOS:

  • Ensure profile was actually installed (check VPN & Device Management)

  • AirDrop may fail if devices not on same network - use USB instead

"Wrong Password" During Import

  • Verify PKCS#12 export password (not private key passphrase)

  • Re-export with known password:

# On certmgr-01, re-create PKCS#12 from existing cert.json
jq -r '.data.certificate' zfold7-cert.json > cert.pem
jq -r '.data.private_key' zfold7-cert.json > key.pem
jq -r '.data.ca_chain[]' zfold7-cert.json > ca.pem

# Export with simpler password for testing
openssl pkcs12 -export \
  -out zfold7-evanusmodestus-test.p12 \
  -inkey key.pem \
  -in cert.pem \
  -certfile ca.pem \
  -password pass:test1234

shred -u key.pem cert.pem ca.pem

Certificate Imported But 802.1X Fails

  1. Verify certificate is selected in WiFi settings

  2. Check CA chain trust (device may not trust DOMUS-ROOT-CA)

  3. Verify ISE policy allows BYOD certificates

  4. Check ISE RADIUS live logs for rejection reason

See BYOD Policy Configuration for ISE troubleshooting.

Security Considerations

Private Key Protection

  • Private key NEVER leaves certmgr-01 unencrypted (only in PKCS#12)

  • PKCS#12 export password protects key during transfer

  • Device stores key in hardware-backed keystore (Android Keystore, iOS Secure Enclave)

Certificate Revocation

To revoke a BYOD certificate:

# On certmgr-01
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN="<your-token>"

# Revoke by serial number
vault write pki_int/revoke serial_number="<serial>"

# Verify revocation
vault read pki_int/cert/<serial>

CRL/OCSP Not Yet Configured

Vault CRL/OCSP endpoints are not configured. Revoked certificates will still work until ISE is configured to check revocation status.

Future enhancement: Configure Vault CRL endpoint and ISE to validate revocation.

Next Steps

  • Configure ISE BYOD Policy

  • Test 802.1X authentication to Domus-Secure SSID

  • Monitor ISE RADIUS live logs during first authentication

  • Document device-specific quirks and troubleshooting