Access Control and Permissions
Introduction
This page documents the access control system that governs what operations a service instance can perform at runtime. AosCore implements a fixed, manifest-driven permission model — permissions are declared per-service in the OCI item configuration and enforced through a secret-based authentication mechanism managed by the Permission Handler (PermHandler) within IAM.
This is not a configurable RBAC system. OEMs do not define or modify permission policies at runtime. Instead, the cloud-side orchestration system declares what each service is allowed to do when it builds the service image, and the on-device access control system enforces those declarations without modification.
Access Control Model Overview
The access control model operates on a simple principle: a service instance can only access the functional server capabilities explicitly granted to it in its deployment manifest.
The model has three participants:
| Participant | Role |
|---|---|
| Service instance | A running container or native process that needs to access system capabilities through functional servers |
| Functional server | A system service that exposes capabilities (e.g., vehicle signal access, system core operations) and enforces permission checks |
| IAM (PermHandler) | The central authority that stores permission mappings and validates access requests from functional servers |
The flow works as follows:
- When SM launches a service instance, it registers the instance's declared permissions with IAM
- IAM generates a unique secret (UUID v4) and returns it to SM
- SM injects the secret into the service's environment as
AOS_SECRET - When the service calls a functional server, it presents its secret
- The functional server validates the secret against IAM's public permissions API
- IAM returns the permissions associated with that secret for the specific functional server
- The functional server enforces the returned permissions
Permission Declaration
Permissions are declared in the OCI item configuration (ItemConfig) that accompanies each service image. The
mPermissions field contains an array of FunctionServicePermissions entries — one per functional server the service
needs to access.
Each entry specifies:
- Functional server name — identifies which functional server the permissions apply to (e.g.,
"vis"for Vehicle Information Service,"systemCore"for system core operations) - Permission mappings — a list of key-value pairs where the key identifies a resource or operation and the value specifies the access level
Permission Structure
ItemConfig.mPermissions = [
FunctionServicePermissions {
mName: "vis" // functional server ID
mPermissions: [
{ mFunction: "*", mPermissions: "rw" }, // all signals, read-write
{ mFunction: "test", mPermissions: "r" } // test signal, read-only
]
},
FunctionServicePermissions {
mName: "systemCore"
mPermissions: [
{ mFunction: "test1.*", mPermissions: "rw" },
{ mFunction: "test2", mPermissions: "r" }
]
}
]
The permission key format and semantics are defined by each functional server — IAM does not interpret them. IAM stores and returns them verbatim; enforcement logic lives in the functional server.
Secret-Based Authentication
When a service instance is deployed with non-empty permissions, the launcher registers it with IAM's PermHandler. The registration flow:
- SM calls
RegisterInstance— passes the instance identity (InstanceIdent: item ID, subject ID, instance index) and the full permissions array from the item config - PermHandler generates a UUID v4 secret — a cryptographically random 36-character string (standard UUID format) generated through the system's crypto provider
- PermHandler stores the mapping — the secret, instance identity, and permissions are stored in an in-memory cache (not persisted to disk)
- Secret returned to SM — SM injects it into the service container as the
AOS_SECRETenvironment variable
If the same instance is registered again (e.g., after a restart without unregistration), the PermHandler returns the existing secret from cache rather than generating a new one.
Secret Properties
| Property | Value |
|---|---|
| Format | UUID v4 string (36 characters, e.g., 550e8400-e29b-41d4-a716-446655440000) |
| Generation | Cryptographically random via the system's UUID provider |
| Uniqueness | Guaranteed unique across all registered instances (collision check on generation) |
| Storage | In-memory only — not persisted across IAM restarts |
| Lifetime | Valid from RegisterInstance until UnregisterInstance or IAM restart |
| Delivery | Injected as AOS_SECRET environment variable in the service container |
Permission Validation Flow
When a service needs to access a functional server capability, the following validation occurs:
Step 1: Service Presents Secret
The service includes its AOS_SECRET value when calling the functional server. The mechanism for presenting the secret
is defined by the functional server's protocol (typically as a header or parameter in the request).
Step 2: Functional Server Queries IAM
The functional server calls IAM's public gRPC API (IAMPublicPermissionsService.GetPermissions) with:
secret— the secret presented by the servicefunctional_server_id— the functional server's own identifier (e.g.,"vis")
This API is on IAM's public server (no mutual TLS required), making it accessible to functional servers that may not have IAM-issued certificates.
Step 3: IAM Resolves Permissions
The PermHandler:
- Looks up the secret in its in-memory cache
- If found, locates the permission entry matching the requested
functional_server_id - Returns the instance identity and the permission mappings for that functional server
Step 4: Functional Server Enforces
The functional server receives the permission mappings (key-value pairs) and applies its own enforcement logic. For example, a Vehicle Information Service might check if the requested signal path matches any of the permitted function patterns.
Error Cases
| Condition | Result |
|---|---|
| Unknown secret | eNotFound error — the service is not registered or IAM has restarted |
| Unknown functional server ID | eNotFound error — the service has no permissions for this functional server |
| Service has no permissions declared | No secret is generated; AOS_SECRET is not set in the environment |
Instance Lifecycle Integration
The permission system is tightly integrated with the service instance lifecycle:
Registration (Instance Start)
During instance startup, the container runtime checks if the item config declares any permissions. If
itemConfig.mPermissions is non-empty:
- The launcher calls
RegisterInstanceon the PermHandler (via IAM's protected gRPC API) - The returned secret is formatted as
AOS_SECRET=<uuid>and added to the container's environment variables - A flag (
mPermissionsRegistered) is set to track that cleanup is needed on stop
If the item config has no permissions, no registration occurs and AOS_SECRET is not set.
Unregistration (Instance Stop)
When a service instance stops (gracefully or due to failure):
- If permissions were registered, the launcher calls
UnregisterInstance - The PermHandler removes the instance's secret and permission mappings from the in-memory cache
- Any subsequent
GetPermissionscalls with that secret will returneNotFound
IAM Restart
Since permissions are stored in memory only, an IAM restart clears all registered permissions. After IAM restarts:
- All existing secrets become invalid
- Functional servers will receive
eNotFoundfor any permission queries - Services must be re-registered (typically through a service restart triggered by SM)
gRPC API Reference
The permission system exposes two gRPC services:
IAMPermissionsService (Protected)
Used by SM to register and unregister service instances. Requires mutual TLS authentication.
| RPC | Request | Response | Description |
|---|---|---|---|
RegisterInstance | InstanceIdent + map<string, Permissions> | secret (string) | Register instance permissions, receive secret |
UnregisterInstance | InstanceIdent | Empty | Remove instance permissions |
IAMPublicPermissionsService (Public)
Used by functional servers to validate service secrets. No mutual TLS required.
| RPC | Request | Response | Description |
|---|---|---|---|
GetPermissions | secret + functional_server_id | InstanceIdent + Permissions | Validate secret and retrieve permissions |
The Permissions message is a map<string, string> — the keys and values are opaque to IAM and interpreted only by the
functional server.
Security Properties
The access control system provides the following security guarantees:
| Property | Mechanism |
|---|---|
| Least privilege | Services can only access capabilities explicitly declared in their item config |
| No privilege escalation | Permissions are fixed at deployment time — a service cannot request additional permissions at runtime |
| Secret isolation | Each instance receives a unique secret; one service cannot impersonate another |
| Revocation on stop | Permissions are immediately revoked when an instance is unregistered |
| Manifest integrity | The item config (including permissions) is part of the OCI image verified during deployment |
Limitations
| Limitation | Implication |
|---|---|
| In-memory storage | Permissions do not survive IAM restarts — services must be re-registered |
| No runtime modification | Permissions cannot be changed without redeploying the service with a new item config |
| No audit trail | Permission checks are logged at debug level but there is no persistent audit log |
| Trust in SM | SM is trusted to register correct permissions — it reads them from the verified item config |
Related Pages
- Identity and Access Manager — IAM component architecture and the PermHandler's place within it
- Permission Model — detailed IAM-internal permission model implementation
- Security Model Overview — the broader security architecture including certificate-based identity and mTLS
- Service Instance States — how instance lifecycle transitions trigger permission registration and unregistration
- Runtime Types — how the container runtime injects the secret into the service environment