diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
new file mode 100644
index 0000000..548b038
--- /dev/null
+++ b/ui/build/paths/config.go
@@ -0,0 +1,160 @@
+// Copyright 2018 Google Inc. All rights reserved.
+//
+// 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.
+
+package paths
+
+import "runtime"
+
+type PathConfig struct {
+	// Whether to create the symlink in the new PATH for this tool.
+	Symlink bool
+
+	// Whether to log about usages of this tool to the soong.log
+	Log bool
+
+	// Whether to exit with an error instead of invoking the underlying tool.
+	Error bool
+}
+
+var Allowed = PathConfig{
+	Symlink: true,
+	Log:     false,
+	Error:   false,
+}
+
+var Forbidden = PathConfig{
+	Symlink: false,
+	Log:     true,
+	Error:   true,
+}
+
+// The configuration used if the tool is not listed in the config below.
+// Currently this will create the symlink, but log a warning. In the future,
+// I expect this to move closer to Forbidden.
+var Missing = PathConfig{
+	Symlink: true,
+	Log:     true,
+	Error:   false,
+}
+
+func GetConfig(name string) PathConfig {
+	if config, ok := Configuration[name]; ok {
+		return config
+	}
+	return Missing
+}
+
+var Configuration = map[string]PathConfig{
+	"awk":       Allowed,
+	"basename":  Allowed,
+	"bash":      Allowed,
+	"bzip2":     Allowed,
+	"cat":       Allowed,
+	"chmod":     Allowed,
+	"cmp":       Allowed,
+	"comm":      Allowed,
+	"cp":        Allowed,
+	"cut":       Allowed,
+	"date":      Allowed,
+	"dd":        Allowed,
+	"diff":      Allowed,
+	"dirname":   Allowed,
+	"echo":      Allowed,
+	"egrep":     Allowed,
+	"env":       Allowed,
+	"expr":      Allowed,
+	"find":      Allowed,
+	"getconf":   Allowed,
+	"getopt":    Allowed,
+	"git":       Allowed,
+	"grep":      Allowed,
+	"gzip":      Allowed,
+	"head":      Allowed,
+	"hexdump":   Allowed,
+	"hostname":  Allowed,
+	"jar":       Allowed,
+	"java":      Allowed,
+	"javap":     Allowed,
+	"ln":        Allowed,
+	"ls":        Allowed,
+	"m4":        Allowed,
+	"make":      Allowed,
+	"md5sum":    Allowed,
+	"mkdir":     Allowed,
+	"mktemp":    Allowed,
+	"mv":        Allowed,
+	"openssl":   Allowed,
+	"patch":     Allowed,
+	"perl":      Allowed,
+	"pstree":    Allowed,
+	"python":    Allowed,
+	"python2.7": Allowed,
+	"python3":   Allowed,
+	"readlink":  Allowed,
+	"realpath":  Allowed,
+	"rm":        Allowed,
+	"rsync":     Allowed,
+	"runalarm":  Allowed,
+	"sed":       Allowed,
+	"setsid":    Allowed,
+	"sh":        Allowed,
+	"sha256sum": Allowed,
+	"sha512sum": Allowed,
+	"sort":      Allowed,
+	"stat":      Allowed,
+	"sum":       Allowed,
+	"tar":       Allowed,
+	"tail":      Allowed,
+	"touch":     Allowed,
+	"tr":        Allowed,
+	"true":      Allowed,
+	"uname":     Allowed,
+	"uniq":      Allowed,
+	"unzip":     Allowed,
+	"wc":        Allowed,
+	"which":     Allowed,
+	"whoami":    Allowed,
+	"xargs":     Allowed,
+	"xmllint":   Allowed,
+	"xz":        Allowed,
+	"zip":       Allowed,
+	"zipinfo":   Allowed,
+
+	// Host toolchain is removed. In-tree toolchain should be used instead.
+	// GCC also can't find cc1 with this implementation.
+	"ar":         Forbidden,
+	"as":         Forbidden,
+	"cc":         Forbidden,
+	"clang":      Forbidden,
+	"clang++":    Forbidden,
+	"gcc":        Forbidden,
+	"g++":        Forbidden,
+	"ld":         Forbidden,
+	"ld.bfd":     Forbidden,
+	"ld.gold":    Forbidden,
+	"pkg-config": Forbidden,
+
+	// We've got prebuilts of these
+	//"dtc":  Forbidden,
+	//"lz4":  Forbidden,
+	//"lz4c": Forbidden,
+}
+
+func init() {
+	if runtime.GOOS == "darwin" {
+		Configuration["md5"] = Allowed
+		Configuration["sw_vers"] = Allowed
+		Configuration["xcrun"] = Allowed
+	}
+}
diff --git a/ui/build/paths/logs.go b/ui/build/paths/logs.go
new file mode 100644
index 0000000..6c24968
--- /dev/null
+++ b/ui/build/paths/logs.go
@@ -0,0 +1,211 @@
+// Copyright 2018 Google Inc. All rights reserved.
+//
+// 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.
+
+package paths
+
+import (
+	"context"
+	"encoding/gob"
+	"fmt"
+	"io/ioutil"
+	"net"
+	"os"
+	"path/filepath"
+	"runtime"
+	"sync"
+	"syscall"
+	"time"
+)
+
+type LogProcess struct {
+	Pid     int
+	Command string
+}
+
+type LogEntry struct {
+	Basename string
+	Args     []string
+	Parents  []LogProcess
+}
+
+const timeoutDuration = time.Duration(100) * time.Millisecond
+
+type socketAddrFunc func(string) (string, func(), error)
+
+func procFallback(name string) (string, func(), error) {
+	d, err := os.Open(filepath.Dir(name))
+	if err != nil {
+		return "", func() {}, err
+	}
+
+	return fmt.Sprintf("/proc/self/fd/%d/%s", d.Fd(), filepath.Base(name)), func() {
+		d.Close()
+	}, nil
+}
+
+func tmpFallback(name string) (addr string, cleanup func(), err error) {
+	d, err := ioutil.TempDir("/tmp", "log_sock")
+	if err != nil {
+		cleanup = func() {}
+		return
+	}
+	cleanup = func() {
+		os.RemoveAll(d)
+	}
+
+	dir := filepath.Dir(name)
+
+	absDir, err := filepath.Abs(dir)
+	if err != nil {
+		return
+	}
+
+	err = os.Symlink(absDir, filepath.Join(d, "d"))
+	if err != nil {
+		return
+	}
+
+	addr = filepath.Join(d, "d", filepath.Base(name))
+
+	return
+}
+
+func getSocketAddr(name string) (string, func(), error) {
+	maxNameLen := len(syscall.RawSockaddrUnix{}.Path)
+
+	if len(name) < maxNameLen {
+		return name, func() {}, nil
+	}
+
+	if runtime.GOOS == "linux" {
+		addr, cleanup, err := procFallback(name)
+		if err == nil {
+			if len(addr) < maxNameLen {
+				return addr, cleanup, nil
+			}
+		}
+		cleanup()
+	}
+
+	addr, cleanup, err := tmpFallback(name)
+	if err == nil {
+		if len(addr) < maxNameLen {
+			return addr, cleanup, nil
+		}
+	}
+	cleanup()
+
+	return name, func() {}, fmt.Errorf("Path to socket is still over size limit, fallbacks failed.")
+}
+
+func dial(name string, lookup socketAddrFunc, timeout time.Duration) (net.Conn, error) {
+	socket, cleanup, err := lookup(name)
+	defer cleanup()
+	if err != nil {
+		return nil, err
+	}
+
+	dialer := &net.Dialer{
+		Timeout: timeout,
+	}
+	return dialer.Dial("unix", socket)
+}
+
+func listen(name string, lookup socketAddrFunc) (net.Listener, error) {
+	socket, cleanup, err := lookup(name)
+	defer cleanup()
+	if err != nil {
+		return nil, err
+	}
+
+	return net.Listen("unix", socket)
+}
+
+func SendLog(logSocket string, entry *LogEntry, done chan interface{}) {
+	sendLog(logSocket, getSocketAddr, timeoutDuration, entry, done)
+}
+
+func sendLog(logSocket string, lookup socketAddrFunc, timeout time.Duration, entry *LogEntry, done chan interface{}) {
+	defer close(done)
+
+	conn, err := dial(logSocket, lookup, timeout)
+	if err != nil {
+		return
+	}
+	defer conn.Close()
+
+	if timeout != 0 {
+		conn.SetDeadline(time.Now().Add(timeout))
+	}
+
+	enc := gob.NewEncoder(conn)
+	enc.Encode(entry)
+}
+
+func LogListener(ctx context.Context, logSocket string) (chan *LogEntry, error) {
+	return logListener(ctx, logSocket, getSocketAddr)
+}
+
+func logListener(ctx context.Context, logSocket string, lookup socketAddrFunc) (chan *LogEntry, error) {
+	ret := make(chan *LogEntry, 5)
+
+	if err := os.Remove(logSocket); err != nil && !os.IsNotExist(err) {
+		return nil, err
+	}
+
+	ln, err := listen(logSocket, lookup)
+	if err != nil {
+		return nil, err
+	}
+
+	go func() {
+		for {
+			select {
+			case <-ctx.Done():
+				ln.Close()
+			}
+		}
+	}()
+
+	go func() {
+		var wg sync.WaitGroup
+		defer func() {
+			wg.Wait()
+			close(ret)
+		}()
+
+		for {
+			conn, err := ln.Accept()
+			if err != nil {
+				ln.Close()
+				break
+			}
+			conn.SetDeadline(time.Now().Add(timeoutDuration))
+			wg.Add(1)
+
+			go func() {
+				defer wg.Done()
+				defer conn.Close()
+
+				dec := gob.NewDecoder(conn)
+				entry := &LogEntry{}
+				if err := dec.Decode(entry); err != nil {
+					return
+				}
+				ret <- entry
+			}()
+		}
+	}()
+	return ret, nil
+}
diff --git a/ui/build/paths/logs_test.go b/ui/build/paths/logs_test.go
new file mode 100644
index 0000000..3b1005f
--- /dev/null
+++ b/ui/build/paths/logs_test.go
@@ -0,0 +1,154 @@
+// Copyright 2018 Google Inc. All rights reserved.
+//
+// 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.
+
+package paths
+
+import (
+	"context"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+func TestSendLog(t *testing.T) {
+	t.Run("Short name", func(t *testing.T) {
+		d, err := ioutil.TempDir("", "s")
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer os.RemoveAll(d)
+		f := filepath.Join(d, "s")
+
+		testSendLog(t, f, getSocketAddr)
+	})
+
+	testLongName := func(t *testing.T, lookup socketAddrFunc) {
+		d, err := ioutil.TempDir("", strings.Repeat("s", 150))
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer os.RemoveAll(d)
+		f := filepath.Join(d, strings.Repeat("s", 10))
+
+		testSendLog(t, f, lookup)
+	}
+
+	// Using a name longer than the ~100 limit of the underlying calls to bind, etc
+	t.Run("Long name", func(t *testing.T) {
+		testLongName(t, getSocketAddr)
+	})
+
+	if runtime.GOOS == "linux" {
+		t.Run("Long name proc fallback", func(t *testing.T) {
+			testLongName(t, procFallback)
+		})
+	}
+
+	t.Run("Long name tmp fallback", func(t *testing.T) {
+		testLongName(t, tmpFallback)
+	})
+}
+
+func testSendLog(t *testing.T, socket string, lookup socketAddrFunc) {
+	recv, err := logListener(context.Background(), socket, lookup)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	go func() {
+		for i := 0; i < 10; i++ {
+			sendLog(socket, lookup, 0, &LogEntry{
+				Basename: "test",
+				Args:     []string{"foo", "bar"},
+			}, make(chan interface{}))
+		}
+	}()
+
+	count := 0
+	for {
+		entry := <-recv
+		if entry == nil {
+			if count != 10 {
+				t.Errorf("Expected 10 logs, got %d", count)
+			}
+			return
+		}
+
+		ref := LogEntry{
+			Basename: "test",
+			Args:     []string{"foo", "bar"},
+		}
+		if !reflect.DeepEqual(ref, *entry) {
+			t.Fatalf("Bad log entry: %v", entry)
+		}
+		count++
+
+		if count == 10 {
+			return
+		}
+	}
+}
+
+func TestSendLogError(t *testing.T) {
+	d, err := ioutil.TempDir("", "log_socket")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(d)
+
+	// Missing log sockets should not block waiting for the timeout to elapse
+	t.Run("Missing file", func(t *testing.T) {
+		sendLog(filepath.Join(d, "missing"), getSocketAddr, 0, &LogEntry{}, make(chan interface{}))
+	})
+
+	// Non-sockets should not block waiting for the timeout to elapse
+	t.Run("Regular file", func(t *testing.T) {
+		f := filepath.Join(d, "file")
+		if fp, err := os.Create(f); err == nil {
+			fp.Close()
+		} else {
+			t.Fatal(err)
+		}
+
+		sendLog(f, getSocketAddr, 0, &LogEntry{}, make(chan interface{}))
+	})
+
+	// If the reader is stuck, we should be able to make progress
+	t.Run("Reader not reading", func(t *testing.T) {
+		f := filepath.Join(d, "sock1")
+
+		ln, err := listen(f, getSocketAddr)
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer ln.Close()
+
+		done := make(chan bool, 1)
+		go func() {
+			for i := 0; i < 10; i++ {
+				sendLog(f, getSocketAddr, timeoutDuration, &LogEntry{
+					// Ensure a relatively large payload
+					Basename: strings.Repeat(" ", 100000),
+				}, make(chan interface{}))
+			}
+			done <- true
+		}()
+
+		<-done
+	})
+}
