diff --git a/compos/src/compsvc.rs b/compos/src/compsvc.rs
new file mode 100644
index 0000000..e912463
--- /dev/null
+++ b/compos/src/compsvc.rs
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! compsvc is a service to run computational tasks in a PVM upon request. It is able to set up
+//! file descriptors backed by fd_server and pass the file descriptors to the actual tasks for
+//! read/write. The service also attempts to sandbox the execution so that one task cannot leak or
+//! impact future tasks.
+//!
+//! Example:
+//! $ compsvc /system/bin/sleep
+//!
+//! The current architecture / process hierarchy looks like:
+//! - compsvc (handle requests)
+//!   - compsvc_worker (for environment setup)
+//!     - authfs (fd translation)
+//!     - actual task
+
+use anyhow::{bail, Context, Result};
+use log::error;
+use minijail::{self, Minijail};
+use std::path::PathBuf;
+
+use compos_aidl_interface::aidl::com::android::compos::ICompService::{
+    BnCompService, ICompService,
+};
+use compos_aidl_interface::aidl::com::android::compos::Metadata::Metadata;
+use compos_aidl_interface::binder::{
+    add_service, BinderFeatures, Interface, ProcessState, Result as BinderResult, Status,
+    StatusCode, Strong,
+};
+
+const SERVICE_NAME: &str = "compsvc";
+// TODO(b/161470604): Move the executable into an apex.
+const WORKER_BIN: &str = "/system/bin/compsvc_worker";
+// TODO: Replace with a valid directory setup in the VM.
+const AUTHFS_MOUNTPOINT: &str = "/data/local/tmp/authfs_mnt";
+
+struct CompService {
+    worker_bin: PathBuf,
+    task_bin: String,
+    debuggable: bool,
+}
+
+impl CompService {
+    pub fn new_binder(service: CompService) -> Strong<dyn ICompService> {
+        BnCompService::new_binder(service, BinderFeatures::default())
+    }
+
+    fn run_worker_in_jail_and_wait(&self, args: &[String]) -> Result<(), minijail::Error> {
+        let mut jail = Minijail::new()?;
+
+        // TODO(b/185175567): New user and uid namespace when supported. Run as nobody.
+        // New mount namespace to isolate the FUSE mount.
+        jail.namespace_vfs();
+
+        let inheritable_fds = if self.debuggable {
+            vec![1, 2] // inherit/redirect stdout/stderr for debugging
+        } else {
+            vec![]
+        };
+        let _pid = jail.run(&self.worker_bin, &inheritable_fds, &args)?;
+        jail.wait()
+    }
+
+    fn build_worker_args(&self, args: &[String], metadata: &Metadata) -> Vec<String> {
+        let mut worker_args = vec![
+            WORKER_BIN.to_string(),
+            "--authfs-root".to_string(),
+            AUTHFS_MOUNTPOINT.to_string(),
+        ];
+        for annotation in &metadata.input_fd_annotations {
+            worker_args.push("--in-fd".to_string());
+            worker_args.push(format!("{}:{}", annotation.fd, annotation.file_size));
+        }
+        for annotation in &metadata.output_fd_annotations {
+            worker_args.push("--out-fd".to_string());
+            worker_args.push(annotation.fd.to_string());
+        }
+        if self.debuggable {
+            worker_args.push("--debug".to_string());
+        }
+        worker_args.push("--".to_string());
+
+        // Do not accept arbitrary code execution. We want to execute some specific task of this
+        // service. Use the associated executable.
+        worker_args.push(self.task_bin.clone());
+        worker_args.extend_from_slice(&args[1..]);
+        worker_args
+    }
+}
+
+impl Interface for CompService {}
+
+impl ICompService for CompService {
+    fn execute(&self, args: &[String], metadata: &Metadata) -> BinderResult<i8> {
+        let worker_args = self.build_worker_args(args, metadata);
+
+        match self.run_worker_in_jail_and_wait(&worker_args) {
+            Ok(_) => Ok(0), // TODO(b/161471326): Sign the output on succeed.
+            Err(minijail::Error::ReturnCode(exit_code)) => {
+                error!("Task failed with exit code {}", exit_code);
+                Err(Status::from(StatusCode::FAILED_TRANSACTION))
+            }
+            Err(e) => {
+                error!("Unexpected error: {}", e);
+                Err(Status::from(StatusCode::UNKNOWN_ERROR))
+            }
+        }
+    }
+}
+
+fn parse_args() -> Result<CompService> {
+    #[rustfmt::skip]
+    let matches = clap::App::new("compsvc")
+        .arg(clap::Arg::with_name("debug")
+             .long("debug"))
+        .arg(clap::Arg::with_name("task_bin")
+             .required(true))
+        .get_matches();
+
+    Ok(CompService {
+        task_bin: matches.value_of("task_bin").unwrap().to_string(),
+        worker_bin: PathBuf::from(WORKER_BIN),
+        debuggable: matches.is_present("debug"),
+    })
+}
+
+fn main() -> Result<()> {
+    android_logger::init_once(
+        android_logger::Config::default().with_tag("compsvc").with_min_level(log::Level::Debug),
+    );
+
+    let service = parse_args()?;
+
+    ProcessState::start_thread_pool();
+    // TODO: switch to remote binder
+    add_service(SERVICE_NAME, CompService::new_binder(service).as_binder())
+        .with_context(|| format!("Failed to register service {}", SERVICE_NAME))?;
+    ProcessState::join_thread_pool();
+    bail!("Unexpected exit after join_thread_pool")
+}
diff --git a/compos/src/compsvc_worker.rs b/compos/src/compsvc_worker.rs
new file mode 100644
index 0000000..cf40f81
--- /dev/null
+++ b/compos/src/compsvc_worker.rs
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! This executable works as a child/worker for the main compsvc service. This worker is mainly
+//! responsible for setting up the execution environment, e.g. to create file descriptors for
+//! remote file access via an authfs mount.
+
+use anyhow::{bail, Result};
+use log::warn;
+use minijail::Minijail;
+use nix::sys::statfs::{statfs, FsType};
+use std::fs::{File, OpenOptions};
+use std::io;
+use std::os::unix::io::AsRawFd;
+use std::path::Path;
+use std::process::exit;
+use std::thread::sleep;
+use std::time::{Duration, Instant};
+
+const AUTHFS_BIN: &str = "/apex/com.android.virt/bin/authfs";
+const AUTHFS_SETUP_POLL_INTERVAL_MS: Duration = Duration::from_millis(50);
+const AUTHFS_SETUP_TIMEOUT_SEC: Duration = Duration::from_secs(10);
+const FUSE_SUPER_MAGIC: FsType = FsType(0x65735546);
+
+/// The number that hints the future file descriptor. These are not really file descriptor, but
+/// represents the file descriptor number to pass to the task.
+type PseudoRawFd = i32;
+
+fn is_fuse(path: &str) -> Result<bool> {
+    Ok(statfs(path)?.filesystem_type() == FUSE_SUPER_MAGIC)
+}
+
+fn spawn_authfs(config: &Config) -> Result<Minijail> {
+    // TODO(b/185175567): Run in a more restricted sandbox.
+    let jail = Minijail::new()?;
+
+    let mut args = vec![AUTHFS_BIN.to_string(), config.authfs_root.clone()];
+    for conf in &config.in_fds {
+        // TODO(b/185178698): Many input files need to be signed and verified.
+        // or can we use debug cert for now, which is better than nothing?
+        args.push("--remote-ro-file-unverified".to_string());
+        args.push(format!("{}:{}:{}", conf.fd, conf.fd, conf.file_size));
+    }
+    for conf in &config.out_fds {
+        args.push("--remote-new-rw-file".to_string());
+        args.push(format!("{}:{}", conf.fd, conf.fd));
+    }
+
+    let preserve_fds = if config.debuggable {
+        vec![1, 2] // inherit/redirect stdout/stderr for debugging
+    } else {
+        vec![]
+    };
+
+    let _pid = jail.run(Path::new(AUTHFS_BIN), &preserve_fds, &args)?;
+    Ok(jail)
+}
+
+fn wait_until_authfs_ready(authfs_root: &str) -> Result<()> {
+    let start_time = Instant::now();
+    loop {
+        if is_fuse(authfs_root)? {
+            break;
+        }
+        if start_time.elapsed() > AUTHFS_SETUP_TIMEOUT_SEC {
+            bail!("Time out mounting authfs");
+        }
+        sleep(AUTHFS_SETUP_POLL_INTERVAL_MS);
+    }
+    Ok(())
+}
+
+fn open_authfs_file(authfs_root: &str, basename: PseudoRawFd, writable: bool) -> io::Result<File> {
+    OpenOptions::new().read(true).write(writable).open(format!("{}/{}", authfs_root, basename))
+}
+
+fn open_authfs_files_for_mapping(config: &Config) -> io::Result<Vec<(File, PseudoRawFd)>> {
+    let mut fd_mapping = Vec::with_capacity(config.in_fds.len() + config.out_fds.len());
+
+    let results: io::Result<Vec<_>> = config
+        .in_fds
+        .iter()
+        .map(|conf| Ok((open_authfs_file(&config.authfs_root, conf.fd, false)?, conf.fd)))
+        .collect();
+    fd_mapping.append(&mut results?);
+
+    let results: io::Result<Vec<_>> = config
+        .out_fds
+        .iter()
+        .map(|conf| Ok((open_authfs_file(&config.authfs_root, conf.fd, true)?, conf.fd)))
+        .collect();
+    fd_mapping.append(&mut results?);
+
+    Ok(fd_mapping)
+}
+
+fn spawn_jailed_task(config: &Config, fd_mapping: Vec<(File, PseudoRawFd)>) -> Result<Minijail> {
+    // TODO(b/185175567): Run in a more restricted sandbox.
+    let jail = Minijail::new()?;
+    let mut preserve_fds: Vec<_> = fd_mapping.iter().map(|(f, id)| (f.as_raw_fd(), *id)).collect();
+    if config.debuggable {
+        // inherit/redirect stdout/stderr for debugging
+        preserve_fds.push((1, 1));
+        preserve_fds.push((2, 2));
+    }
+    let _pid =
+        jail.run_remap(&Path::new(&config.args[0]), preserve_fds.as_slice(), &config.args)?;
+    Ok(jail)
+}
+
+struct InFdAnnotation {
+    fd: PseudoRawFd,
+    file_size: u64,
+}
+
+struct OutFdAnnotation {
+    fd: PseudoRawFd,
+}
+
+struct Config {
+    authfs_root: String,
+    in_fds: Vec<InFdAnnotation>,
+    out_fds: Vec<OutFdAnnotation>,
+    args: Vec<String>,
+    debuggable: bool,
+}
+
+fn parse_args() -> Result<Config> {
+    #[rustfmt::skip]
+    let matches = clap::App::new("compsvc_worker")
+        .arg(clap::Arg::with_name("authfs-root")
+             .long("authfs-root")
+             .value_name("DIR")
+             .required(true)
+             .takes_value(true))
+        .arg(clap::Arg::with_name("in-fd")
+             .long("in-fd")
+             .multiple(true)
+             .takes_value(true)
+             .requires("authfs-root"))
+        .arg(clap::Arg::with_name("out-fd")
+             .long("out-fd")
+             .multiple(true)
+             .takes_value(true)
+             .requires("authfs-root"))
+        .arg(clap::Arg::with_name("debug")
+             .long("debug"))
+        .arg(clap::Arg::with_name("args")
+             .last(true)
+             .required(true)
+             .multiple(true))
+        .get_matches();
+
+    // Safe to unwrap since the arg is required by the clap rule
+    let authfs_root = matches.value_of("authfs-root").unwrap().to_string();
+
+    let results: Result<Vec<_>> = matches
+        .values_of("in-fd")
+        .unwrap_or_default()
+        .into_iter()
+        .map(|arg| {
+            if let Some(index) = arg.find(':') {
+                let (fd, size) = arg.split_at(index);
+                Ok(InFdAnnotation { fd: fd.parse()?, file_size: size[1..].parse()? })
+            } else {
+                bail!("Invalid argument: {}", arg);
+            }
+        })
+        .collect();
+    let in_fds = results?;
+
+    let results: Result<Vec<_>> = matches
+        .values_of("out-fd")
+        .unwrap_or_default()
+        .into_iter()
+        .map(|arg| Ok(OutFdAnnotation { fd: arg.parse()? }))
+        .collect();
+    let out_fds = results?;
+
+    let args: Vec<_> = matches.values_of("args").unwrap().map(|s| s.to_string()).collect();
+    let debuggable = matches.is_present("debug");
+
+    Ok(Config { authfs_root, in_fds, out_fds, args, debuggable })
+}
+
+fn main() -> Result<()> {
+    let log_level =
+        if env!("TARGET_BUILD_VARIANT") == "eng" { log::Level::Trace } else { log::Level::Info };
+    android_logger::init_once(
+        android_logger::Config::default().with_tag("compsvc_worker").with_min_level(log_level),
+    );
+
+    let config = parse_args()?;
+
+    let authfs_jail = spawn_authfs(&config)?;
+    let authfs_lifetime = scopeguard::guard(authfs_jail, |authfs_jail| {
+        if let Err(e) = authfs_jail.kill() {
+            if !matches!(e, minijail::Error::Killed(_)) {
+                warn!("Failed to kill authfs: {}", e);
+            }
+        }
+    });
+
+    wait_until_authfs_ready(&config.authfs_root)?;
+    let fd_mapping = open_authfs_files_for_mapping(&config)?;
+
+    let jail = spawn_jailed_task(&config, fd_mapping)?;
+    let jail_result = jail.wait();
+
+    // Be explicit about the lifetime, which should last at least until the task is finished.
+    drop(authfs_lifetime);
+
+    match jail_result {
+        Ok(_) => Ok(()),
+        Err(minijail::Error::ReturnCode(exit_code)) => {
+            exit(exit_code as i32);
+        }
+        Err(e) => {
+            bail!("Unexpected minijail error: {}", e);
+        }
+    }
+}
diff --git a/compos/src/pvm_exec.rs b/compos/src/pvm_exec.rs
new file mode 100644
index 0000000..fcde266
--- /dev/null
+++ b/compos/src/pvm_exec.rs
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! pvm_exec is a proxy/wrapper command to run a command remotely. It does not transport the
+//! program and just pass the command line arguments to compsvc to execute. The most important task
+//! for this program is to run a `fd_server` that serves remote file read/write requests.
+//!
+//! Example:
+//! $ adb shell exec 3</dev/zero 4<>/dev/null pvm_exec --in-fd 3 --out-fd 4 -- sleep 10
+//!
+//! Note the immediate argument right after "--" (e.g. "sleep" in the example above) is not really
+//! used. It is only for ergonomics.
+
+use anyhow::{bail, Context, Result};
+use log::{error, warn};
+use minijail::Minijail;
+use nix::fcntl::{fcntl, FcntlArg::F_GETFD};
+use nix::sys::stat::fstat;
+use std::os::unix::io::RawFd;
+use std::path::Path;
+use std::process::exit;
+
+use compos_aidl_interface::aidl::com::android::compos::{
+    ICompService::ICompService, InputFdAnnotation::InputFdAnnotation, Metadata::Metadata,
+    OutputFdAnnotation::OutputFdAnnotation,
+};
+use compos_aidl_interface::binder::Strong;
+
+static SERVICE_NAME: &str = "compsvc";
+static FD_SERVER_BIN: &str = "/apex/com.android.virt/bin/fd_server";
+
+fn get_local_service() -> Strong<dyn ICompService> {
+    compos_aidl_interface::binder::get_interface(SERVICE_NAME).expect("Cannot reach compsvc")
+}
+
+fn spawn_fd_server(metadata: &Metadata, debuggable: bool) -> Result<Minijail> {
+    let mut inheritable_fds = if debuggable {
+        vec![1, 2] // inherit/redirect stdout/stderr for debugging
+    } else {
+        vec![]
+    };
+
+    let mut args = vec![FD_SERVER_BIN.to_string()];
+    for metadata in &metadata.input_fd_annotations {
+        args.push("--ro-fds".to_string());
+        args.push(metadata.fd.to_string());
+        inheritable_fds.push(metadata.fd);
+    }
+    for metadata in &metadata.output_fd_annotations {
+        args.push("--rw-fds".to_string());
+        args.push(metadata.fd.to_string());
+        inheritable_fds.push(metadata.fd);
+    }
+
+    let jail = Minijail::new()?;
+    let _pid = jail.run(Path::new(FD_SERVER_BIN), &inheritable_fds, &args)?;
+    Ok(jail)
+}
+
+fn is_fd_valid(fd: RawFd) -> Result<bool> {
+    let retval = fcntl(fd, F_GETFD)?;
+    Ok(retval >= 0)
+}
+
+fn parse_arg_fd(arg: &str) -> Result<RawFd> {
+    let fd = arg.parse::<RawFd>()?;
+    if !is_fd_valid(fd)? {
+        bail!("Bad FD: {}", fd);
+    }
+    Ok(fd)
+}
+
+struct Config {
+    args: Vec<String>,
+    metadata: Metadata,
+    debuggable: bool,
+}
+
+fn parse_args() -> Result<Config> {
+    #[rustfmt::skip]
+    let matches = clap::App::new("pvm_exec")
+        .arg(clap::Arg::with_name("in-fd")
+             .long("in-fd")
+             .takes_value(true)
+             .multiple(true)
+             .use_delimiter(true))
+        .arg(clap::Arg::with_name("out-fd")
+             .long("out-fd")
+             .takes_value(true)
+             .multiple(true)
+             .use_delimiter(true))
+        .arg(clap::Arg::with_name("debug")
+             .long("debug"))
+        .arg(clap::Arg::with_name("args")
+             .last(true)
+             .required(true)
+             .multiple(true))
+        .get_matches();
+
+    let results: Result<Vec<_>> = matches
+        .values_of("in-fd")
+        .unwrap_or_default()
+        .map(|arg| {
+            let fd = parse_arg_fd(arg)?;
+            let file_size = fstat(fd)?.st_size;
+            Ok(InputFdAnnotation { fd, file_size })
+        })
+        .collect();
+    let input_fd_annotations = results?;
+
+    let results: Result<Vec<_>> = matches
+        .values_of("out-fd")
+        .unwrap_or_default()
+        .map(|arg| {
+            let fd = parse_arg_fd(arg)?;
+            Ok(OutputFdAnnotation { fd })
+        })
+        .collect();
+    let output_fd_annotations = results?;
+
+    let args: Vec<_> = matches.values_of("args").unwrap().map(|s| s.to_string()).collect();
+    let debuggable = matches.is_present("debug");
+
+    Ok(Config {
+        args,
+        metadata: Metadata { input_fd_annotations, output_fd_annotations },
+        debuggable,
+    })
+}
+
+fn main() -> Result<()> {
+    // 1. Parse the command line arguments for collect execution data.
+    let Config { args, metadata, debuggable } = parse_args()?;
+
+    // 2. Spawn and configure a fd_server to serve remote read/write requests.
+    let fd_server_jail = spawn_fd_server(&metadata, debuggable)?;
+    let fd_server_lifetime = scopeguard::guard(fd_server_jail, |fd_server_jail| {
+        if let Err(e) = fd_server_jail.kill() {
+            if !matches!(e, minijail::Error::Killed(_)) {
+                warn!("Failed to kill fd_server: {}", e);
+            }
+        }
+    });
+
+    // 3. Send the command line args to the remote to execute.
+    let exit_code = get_local_service().execute(&args, &metadata).context("Binder call failed")?;
+
+    // Be explicit about the lifetime, which should last at least until the task is finished.
+    drop(fd_server_lifetime);
+
+    if exit_code > 0 {
+        error!("remote execution failed with exit code {}", exit_code);
+        exit(exit_code as i32);
+    }
+    Ok(())
+}
