// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.component.internal;

using fuchsia.component;
using fuchsia.sys2;

/// The maximum size of the JobPolicyAllowlists entries.
/// This value is currently set arbitrarily.
const uint64 MAX_ALLOWLIST_SIZE = 128;

table Config {
    /// If true, component manager will be in debug mode. In this mode, component manager
    /// provides the `BlockingEventSource` protocol and exposes this protocol. Component
    /// manager will not start until it is resumed by a call to
    /// `BlockingEventSource.StartComponentTree`.
    ///
    /// This is done so that an external component (say an integration test) can subscribe
    /// to events before the root component has started.
    1: bool debug;

    /// How many children, maximum, are returned by a call to `Realm.ChildIterator.next()`.
    2: uint32 list_children_batch_size;

    /// Security policy configuration.
    3: SecurityPolicy security_policy;

    /// Capabilities offered from component manager's namespace.
    4: vector<fuchsia.sys2.CapabilityDecl>:MAX namespace_capabilities;

    /// If true, component_manager will serve an instance of fuchsia.process.Launcher and use this
    /// launcher for the built-in ELF component runner. The root component can additionally
    /// use and/or offer this service using `/builtin/fuchsia.process.Launcher` from realm.
    /// This flag exists because the built-in process launcher *only* works when
    /// component_manager runs under a job that has ZX_POL_NEW_PROCESS set to allow, like the root
    /// job. Otherwise, the component_manager process cannot directly create process through
    /// zx_process_create. When we run component_manager elsewhere, like in test environments, it
    /// has to use the fuchsia.process.Launcher service provided through its namespace instead.
    5: bool use_builtin_process_launcher;

    /// If true, component_manager will maintain a UTC kernel clock and vend write handles through
    /// an instance of `fuchsia.time.Maintenance`. This flag should only be used with the top-level
    /// component_manager.
    6: bool maintain_utc_clock;

    /// The number of threads to use for running component_manager's executor.
    /// Value defaults to 1.
    7: uint32 num_threads;

    /// Which builtin resolver to use. If not supplied this defaults to the NONE option.
    8: BuiltinPkgResolver builtin_pkg_resolver;

    /// Determine what content to expose through the component manager's
    /// outgoing directory. If no value is set, this defaults to NONE.
    9: OutDirContents out_dir_contents;

    /// URL of the root component to launch. This field is used if the no URL
    /// is passed to component manager. If value is passed in both places, then
    /// an error is raised.
    10: string:fuchsia.component.MAX_URL_SCHEME_LENGTH root_component_url;

    /// Path to the component ID index. An empty value defaults to an empty index.
    /// An invalid index causes component_manager to abort.
    11: string:fuchsia.component.MAX_PATH_LENGTH component_id_index_path;
};

/// The builtin resolver to use, if any.
enum BuiltinPkgResolver : uint8 {
    /// No builtin package resolver is used. Products supply a package resolver as a component, or
    /// can opt to not include one at all.
    NONE = 1;

    /// Try to use the `fuchsia.sys.Loader` protocol from the namespace, typically this is provided
    /// by `appmgr`. Test scenarios commonly use this option.
    APPMGR_BRIDGE = 3;
};

/// Runtime security policy.
table SecurityPolicy {
    /// Allowlists for Zircon job policy.
    1: JobPolicyAllowlists job_policy;
    /// Capability access policy.
    2: CapabilityPolicyAllowlists capability_policy;
};

/// Allowlists for Zircon job policy.
table JobPolicyAllowlists {
    /// Absolute monikers for components allowed to be given the ZX_POL_AMBIENT_MARK_VMO_EXEC job
    /// policy.
    ///
    /// Components must request this policy by including "job_policy_ambient_mark_vmo_exec: true" in
    /// their CML's `program` section and must be using the ELF runner.
    /// This is equivalent to the v1 'deprecated-ambient-replace-as-executable' feature.
    1: vector<string:fuchsia.component.MAX_MONIKER_LENGTH>:MAX_ALLOWLIST_SIZE ambient_mark_vmo_exec;

    /// Absolute monikers for components allowed to have their original process marked as critical
    /// to component_manager's job.
    ///
    /// Components must request this critical marking by including "main_process_critical: true" in
    /// their CML's `program` section and must be using the ELF runner.
    2: vector<string:fuchsia.component.MAX_MONIKER_LENGTH>:MAX_ALLOWLIST_SIZE main_process_critical;
};

/// Determine what content to expose through component manager's outgoing
/// directory.
enum OutDirContents : uint8 {
    /// Don't expose anything through the outgoing directory.
    NONE = 1;

    /// Expose component manager's `hub` directory.
    HUB = 2;

    /// Expose root component's `expose/svc`.
    SVC = 3;
};

/// Represents the class of capabilities supported to be allowlisted.
flexible union AllowlistedCapability {
    1: AllowlistedDirectory directory;
    2: AllowlistedEvent event;
    3: AllowlistedProtocol protocol;
    4: AllowlistedService service;
    5: AllowlistedStorage storage;
    6: AllowlistedRunner runner;
    7: AllowlistedResolver resolver;
};

table AllowlistedDirectory {
};

table AllowlistedEvent {
};

table AllowlistedProtocol {
};

table AllowlistedService {
};

table AllowlistedStorage {
};

table AllowlistedRunner {
};

table AllowlistedResolver {
};

/// Defines a single capability policy entry in the set of capability policy
/// allowlists.
table CapabilityAllowlistEntry {
    /// The `source_moniker` represents the origin of a capability. The
    /// `source_moniker` is either an absolute moniker or '<component_manager>'.
    1: string:fuchsia.component.MAX_MONIKER_LENGTH source_moniker;

    /// The source name of this particular capability.
    2: string:fuchsia.component.MAX_NAME_LENGTH source_name;

    /// Represents the type of capability that is being restricted along
    /// with any other properties required by a particular capability type.
    3: AllowlistedCapability capability;

    /// The set of absolute monikers that are allowed to use this specific
    /// capability.
    4: vector<string:fuchsia.component.MAX_MONIKER_LENGTH>:MAX_ALLOWLIST_SIZE target_monikers;

    /// The original source type of this component, self or framework.
    5: fuchsia.sys2.Ref source;
};

/// Defines the total set of capability allowlists. Each
/// `source_moniker` + `capability` pair must be unique in the vector.
table CapabilityPolicyAllowlists {
    1: vector<CapabilityAllowlistEntry>:MAX_ALLOWLIST_SIZE allowlist;
};
