diff --git a/core/internal/api/BUILD.bazel b/core/internal/api/BUILD.bazel
new file mode 100644
index 0000000..6e3cb2b
--- /dev/null
+++ b/core/internal/api/BUILD.bazel
@@ -0,0 +1,20 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+    name = "go_default_library",
+    srcs = [
+        "cluster.go",
+        "main.go",
+        "setup.go",
+    ],
+    importpath = "git.monogon.dev/source/nexantic.git/core/internal/api",
+    visibility = ["//core:__subpackages__"],
+    deps = [
+        "//core/api/api:go_default_library",
+        "//core/internal/common:go_default_library",
+        "//core/internal/consensus:go_default_library",
+        "@com_github_casbin_casbin//:go_default_library",
+        "@org_golang_google_grpc//:go_default_library",
+        "@org_uber_go_zap//:go_default_library",
+    ],
+)
diff --git a/core/internal/api/cluster.go b/core/internal/api/cluster.go
new file mode 100644
index 0000000..32a5691
--- /dev/null
+++ b/core/internal/api/cluster.go
@@ -0,0 +1,117 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// 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 api
+
+import (
+	"context"
+	"crypto/rand"
+	"encoding/hex"
+	"fmt"
+	schema "git.monogon.dev/source/nexantic.git/core/generated/api"
+	"git.monogon.dev/source/nexantic.git/core/internal/common"
+
+	"errors"
+
+	"go.uber.org/zap"
+)
+
+var (
+	ErrAttestationFailed = errors.New("attestation_failed")
+)
+
+func (s *Server) AddNode(ctx context.Context, req *schema.AddNodeRequest) (*schema.AddNodeResponse, error) {
+	// Setup API client
+	c, err := common.NewSmalltownAPIClient(fmt.Sprintf("%s:%d", req.Host, req.ApiPort))
+	if err != nil {
+		return nil, err
+	}
+
+	// Check attestation
+	nonce := make([]byte, 20)
+	_, err = rand.Read(nonce)
+	if err != nil {
+		return nil, err
+	}
+	hexNonce := hex.EncodeToString(nonce)
+
+	aRes, err := c.Setup.Attest(ctx, &schema.AttestRequest{
+		Challenge: hexNonce,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	//TODO(hendrik): Verify response
+	if aRes.Response != hexNonce {
+		return nil, ErrAttestationFailed
+	}
+
+	// Provision cluster info locally
+	memberID, err := s.consensusService.AddMember(ctx, req.Name, fmt.Sprintf("http://%s:%d", req.Host, req.ConsensusPort))
+	if err != nil {
+		return nil, err
+	}
+
+	s.Logger.Info("Added new node to consensus cluster; provisioning external node now",
+		zap.String("host", req.Host), zap.Uint32("port", req.ApiPort),
+		zap.Uint32("consensus_port", req.ConsensusPort), zap.String("name", req.Name))
+
+	// Provision cluster info externally
+	_, err = c.Setup.ProvisionCluster(ctx, &schema.ProvisionClusterRequest{
+		InitialCluster:    s.consensusService.GetInitialClusterString(),
+		ProvisioningToken: req.Token,
+		ExternalHost:      req.Host,
+		NodeName:          req.Name,
+		TrustBackend:      req.TrustBackend,
+	})
+	if err != nil {
+		// Revert Consensus add member - might fail if consensus cannot be established
+		err2 := s.consensusService.RemoveMember(ctx, memberID)
+		if err2 != nil {
+			return nil, fmt.Errorf("Rollback failed after failed provisioning; err=%v; err_rb=%v", err, err2)
+		}
+		return nil, err
+	}
+	s.Logger.Info("Fully provisioned new node",
+		zap.String("host", req.Host), zap.Uint32("port", req.ApiPort),
+		zap.Uint32("consensus_port", req.ConsensusPort), zap.String("name", req.Name),
+		zap.Uint64("member_id", memberID))
+
+	return &schema.AddNodeResponse{}, nil
+}
+
+func (s *Server) RemoveNode(context.Context, *schema.RemoveNodeRequest) (*schema.RemoveNodeRequest, error) {
+	panic("implement me")
+}
+
+func (s *Server) GetNodes(context.Context, *schema.GetNodesRequest) (*schema.GetNodesResponse, error) {
+	nodes := s.consensusService.GetNodes()
+	resNodes := make([]*schema.Node, len(nodes))
+
+	for i, node := range nodes {
+		resNodes[i] = &schema.Node{
+			Id:      node.ID,
+			Name:    node.Name,
+			Address: node.Address,
+			Synced:  node.Synced,
+		}
+	}
+
+	return &schema.GetNodesResponse{
+		Nodes: resNodes,
+	}, nil
+}
diff --git a/core/internal/api/main.go b/core/internal/api/main.go
new file mode 100644
index 0000000..20c3a3a
--- /dev/null
+++ b/core/internal/api/main.go
@@ -0,0 +1,87 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// 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 api
+
+import (
+	"fmt"
+	schema "git.monogon.dev/source/nexantic.git/core/generated/api"
+	"git.monogon.dev/source/nexantic.git/core/internal/common"
+	"git.monogon.dev/source/nexantic.git/core/internal/consensus"
+	"github.com/casbin/casbin"
+	"go.uber.org/zap"
+	"google.golang.org/grpc"
+	"net"
+)
+
+type (
+	Server struct {
+		*common.BaseService
+
+		ruleEnforcer *casbin.Enforcer
+		setupService common.SetupService
+		grpcServer   *grpc.Server
+
+		consensusService *consensus.Service
+
+		config *Config
+	}
+
+	Config struct {
+		Port uint16
+	}
+)
+
+func NewApiServer(config *Config, logger *zap.Logger, setupService common.SetupService, consensusService *consensus.Service) (*Server, error) {
+	s := &Server{
+		config:           config,
+		setupService:     setupService,
+		consensusService: consensusService,
+	}
+
+	s.BaseService = common.NewBaseService("api", logger, s)
+
+	grpcServer := grpc.NewServer()
+	schema.RegisterClusterManagementServer(grpcServer, s)
+	schema.RegisterSetupServiceServer(grpcServer, s)
+
+	s.grpcServer = grpcServer
+
+	return s, nil
+}
+
+func (s *Server) OnStart() error {
+	listenHost := fmt.Sprintf(":%d", s.config.Port)
+	lis, err := net.Listen("tcp", listenHost)
+	if err != nil {
+		s.Logger.Fatal("failed to listen", zap.Error(err))
+	}
+
+	go func() {
+		err = s.grpcServer.Serve(lis)
+		s.Logger.Error("API server failed", zap.Error(err))
+	}()
+
+	s.Logger.Info("GRPC listening", zap.String("host", listenHost))
+
+	return nil
+}
+
+func (s *Server) OnStop() error {
+	s.grpcServer.Stop()
+
+	return nil
+}
diff --git a/core/internal/api/setup.go b/core/internal/api/setup.go
new file mode 100644
index 0000000..943f203
--- /dev/null
+++ b/core/internal/api/setup.go
@@ -0,0 +1,103 @@
+// Copyright 2020 The Monogon Project Authors.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+// 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 api
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	schema "git.monogon.dev/source/nexantic.git/core/generated/api"
+)
+
+const (
+	MinNameLength = 3
+)
+
+var (
+	ErrInvalidProvisioningToken = errors.New("invalid provisioning token")
+	ErrInvalidNameLength        = fmt.Errorf("name must be at least %d characters long", MinNameLength)
+)
+
+func (s *Server) Setup(c context.Context, r *schema.SetupRequest) (*schema.SetupResponse, error) {
+
+	switch r.Request.(type) {
+	case *schema.SetupRequest_JoinCluster:
+		token, err := s.enterJoinCluster(r.GetJoinCluster())
+		if err != nil {
+			return nil, err
+		}
+
+		return &schema.SetupResponse{
+			Response: &schema.SetupResponse_JoinCluster{
+				JoinCluster: &schema.JoinClusterResponse{
+					ProvisioningToken: token,
+				},
+			},
+		}, nil
+
+	case *schema.SetupRequest_NewCluster:
+		return &schema.SetupResponse{
+			Response: &schema.SetupResponse_NewCluster{
+				NewCluster: &schema.NewClusterResponse{},
+			},
+		}, s.setupNewCluster(r.GetNewCluster())
+	}
+
+	return &schema.SetupResponse{}, nil
+}
+
+func (s *Server) enterJoinCluster(r *schema.JoinClusterRequest) (string, error) {
+	err := s.setupService.EnterJoinClusterMode()
+	if err != nil {
+		return "", err
+	}
+
+	return s.setupService.GetJoinClusterToken(), nil
+}
+
+func (s *Server) setupNewCluster(r *schema.NewClusterRequest) error {
+	if len(r.NodeName) < MinNameLength {
+		return ErrInvalidNameLength
+	}
+	return s.setupService.SetupNewCluster(r.NodeName, r.ExternalHost)
+}
+
+func (s *Server) ProvisionCluster(ctx context.Context, req *schema.ProvisionClusterRequest) (*schema.ProvisionClusterResponse, error) {
+	if len(req.NodeName) < MinNameLength {
+		return nil, ErrInvalidNameLength
+	}
+
+	// Verify provisioning token
+	if s.setupService.GetJoinClusterToken() != req.ProvisioningToken {
+		return nil, ErrInvalidProvisioningToken
+	}
+
+	// Join cluster
+	err := s.setupService.JoinCluster(req.NodeName, req.InitialCluster, req.ExternalHost)
+	if err != nil {
+		return nil, err
+	}
+
+	return &schema.ProvisionClusterResponse{}, nil
+}
+
+func (s *Server) Attest(c context.Context, r *schema.AttestRequest) (*schema.AttestResponse, error) {
+	// TODO implement
+	return &schema.AttestResponse{
+		Response: r.Challenge,
+	}, nil
+}
