up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-28 19:23:54 +02:00
parent d1cbb905f8
commit d040c001ac
36 changed files with 4668 additions and 9 deletions

View File

@@ -415,4 +415,250 @@ policy "Baseline Production Policy" syntax "stella-dsl@1" {
$"pkg:gem/{name}@{version}",
metadataBuilder.ToImmutable());
}
private static PolicyEvaluationComponent CreateMacOsComponent(
string bundleId,
string version,
bool sandboxed = false,
bool hardenedRuntime = false,
string? teamId = null,
string? codeResourcesHash = null,
IEnumerable<string>? categories = null,
IEnumerable<string>? highRiskEntitlements = null,
string? pkgutilIdentifier = null)
{
var metadataBuilder = ImmutableDictionary.CreateBuilder<string, string>(StringComparer.OrdinalIgnoreCase);
metadataBuilder["macos:bundle_id"] = bundleId;
metadataBuilder["macos:sandboxed"] = sandboxed ? "true" : "false";
metadataBuilder["macos:hardened_runtime"] = hardenedRuntime ? "true" : "false";
if (!string.IsNullOrWhiteSpace(teamId))
{
metadataBuilder["macos:team_id"] = teamId;
}
if (!string.IsNullOrWhiteSpace(codeResourcesHash))
{
metadataBuilder["macos:code_resources_hash"] = codeResourcesHash;
}
if (categories is not null && categories.Any())
{
metadataBuilder["macos:capability_categories"] = string.Join(",", categories);
}
if (highRiskEntitlements is not null && highRiskEntitlements.Any())
{
metadataBuilder["macos:high_risk_entitlements"] = string.Join(",", highRiskEntitlements);
}
if (!string.IsNullOrWhiteSpace(pkgutilIdentifier))
{
metadataBuilder["pkgutil:identifier"] = pkgutilIdentifier;
}
return new PolicyEvaluationComponent(
bundleId.Split('.').Last(),
version,
"macos-bundle",
$"pkg:generic/macos-app/{bundleId}@{version}",
metadataBuilder.ToImmutable());
}
#region macOS Policy Predicate Tests
private static readonly string MacOsPolicy = """
policy "macOS Security Policy" syntax "stella-dsl@1" {
metadata {
description = "Enforce macOS bundle security requirements."
tags = ["macos","security"]
}
rule block_unsigned_apps priority 3 {
when sbom.any_component(not macos.signed)
then status := "blocked"
because "Unsigned macOS applications are not permitted."
}
rule warn_high_risk_entitlements priority 4 {
when sbom.any_component(macos.high_risk_entitlements)
then warn message "Application requests high-risk entitlements."
because "High-risk entitlements require review."
}
rule require_hardened_runtime priority 5 {
when sbom.any_component(macos.signed and not macos.hardened_runtime)
then warn message "Application does not use hardened runtime."
because "Hardened runtime is recommended for security."
}
rule block_unsandboxed_apps priority 2 {
when sbom.any_component(not macos.sandboxed)
then warn message "Application is not sandboxed."
because "App sandbox provides security isolation."
}
rule block_camera_microphone priority 1 {
when sbom.any_component(macos.category_any(["camera", "microphone"]))
then warn message "Application accesses camera or microphone."
because "Camera/microphone access requires review."
}
}
""";
[Fact]
public void Evaluate_MacOs_UnsignedAppBlocked()
{
var document = compiler.Compile(MacOsPolicy);
Assert.True(document.Success);
var ir = Assert.IsType<PolicyIrDocument>(document.Document);
// Unsigned but sandboxed app to avoid matching the unsandboxed rule first
var component = CreateMacOsComponent(
bundleId: "com.unknown.UnsignedApp",
version: "1.0.0",
sandboxed: true, // Sandboxed to avoid matching block_unsandboxed_apps first
hardenedRuntime: false,
teamId: null,
codeResourcesHash: null);
var context = CreateContext("Medium", "internal") with
{
Sbom = new PolicyEvaluationSbom(
ImmutableHashSet<string>.Empty,
ImmutableArray.Create(component))
};
var result = evaluationService.Evaluate(ir, context);
Assert.True(result.Matched);
Assert.Equal("block_unsigned_apps", result.RuleName);
Assert.Equal("blocked", result.Status);
}
[Fact]
public void Evaluate_MacOs_SignedAppPasses()
{
var document = compiler.Compile(MacOsPolicy);
Assert.True(document.Success);
var ir = Assert.IsType<PolicyIrDocument>(document.Document);
var component = CreateMacOsComponent(
bundleId: "com.apple.Safari",
version: "17.1",
sandboxed: true,
hardenedRuntime: true,
teamId: "APPLE123",
codeResourcesHash: "sha256:abc123");
var context = CreateContext("Medium", "internal") with
{
Sbom = new PolicyEvaluationSbom(
ImmutableHashSet<string>.Empty,
ImmutableArray.Create(component))
};
var result = evaluationService.Evaluate(ir, context);
// No blocking rules should match for a properly signed and sandboxed app
Assert.False(result.Matched && result.Status == "blocked");
}
[Fact]
public void Evaluate_MacOs_HighRiskEntitlementsWarns()
{
var document = compiler.Compile(MacOsPolicy);
Assert.True(document.Success);
var ir = Assert.IsType<PolicyIrDocument>(document.Document);
// App with high-risk entitlements but no camera/microphone categories
// to avoid matching block_camera_microphone rule first
var component = CreateMacOsComponent(
bundleId: "com.example.AutomationApp",
version: "2.0.0",
sandboxed: true,
hardenedRuntime: true,
teamId: "TEAM123",
codeResourcesHash: "sha256:def456",
categories: new[] { "network", "automation" },
highRiskEntitlements: new[] { "com.apple.security.automation.apple-events" });
var context = CreateContext("Medium", "internal") with
{
Sbom = new PolicyEvaluationSbom(
ImmutableHashSet<string>.Empty,
ImmutableArray.Create(component))
};
var result = evaluationService.Evaluate(ir, context);
Assert.True(result.Matched);
Assert.Equal("warn_high_risk_entitlements", result.RuleName);
Assert.Equal("warned", result.Status);
}
[Fact]
public void Evaluate_MacOs_CategoryMatchesCameraAccess()
{
var document = compiler.Compile(MacOsPolicy);
Assert.True(document.Success);
var ir = Assert.IsType<PolicyIrDocument>(document.Document);
var component = CreateMacOsComponent(
bundleId: "com.example.VideoChat",
version: "1.5.0",
sandboxed: true,
hardenedRuntime: true,
teamId: "TEAM456",
codeResourcesHash: "sha256:ghi789",
categories: new[] { "camera", "microphone", "network" });
var context = CreateContext("Medium", "internal") with
{
Sbom = new PolicyEvaluationSbom(
ImmutableHashSet<string>.Empty,
ImmutableArray.Create(component))
};
var result = evaluationService.Evaluate(ir, context);
// Should match camera/microphone warning rule
Assert.True(result.Matched);
// Either high_risk or camera_microphone rule should match
Assert.True(
result.RuleName == "block_camera_microphone" ||
result.RuleName == "warn_high_risk_entitlements" ||
result.Status == "warned");
}
[Fact]
public void Evaluate_MacOs_HardenedRuntimeWarnsWhenMissing()
{
var document = compiler.Compile(MacOsPolicy);
Assert.True(document.Success);
var ir = Assert.IsType<PolicyIrDocument>(document.Document);
var component = CreateMacOsComponent(
bundleId: "com.example.LegacyApp",
version: "3.0.0",
sandboxed: true,
hardenedRuntime: false,
teamId: "TEAM789",
codeResourcesHash: "sha256:jkl012");
var context = CreateContext("Medium", "internal") with
{
Sbom = new PolicyEvaluationSbom(
ImmutableHashSet<string>.Empty,
ImmutableArray.Create(component))
};
var result = evaluationService.Evaluate(ir, context);
Assert.True(result.Matched);
Assert.Equal("require_hardened_runtime", result.RuleName);
Assert.Equal("warned", result.Status);
}
#endregion
}