diff --git a/src/main/java/info/textgrid/services/aggregator/AggregationTreeWalker.java b/src/main/java/info/textgrid/services/aggregator/AggregationTreeWalker.java
index 80ad34e531d22b0187fd6fd06c22ce258b5e567d..20e0ae01416e198349272d5591ae4e8a6cce2bd7 100644
--- a/src/main/java/info/textgrid/services/aggregator/AggregationTreeWalker.java
+++ b/src/main/java/info/textgrid/services/aggregator/AggregationTreeWalker.java
@@ -15,6 +15,10 @@ public abstract class AggregationTreeWalker {
 
 	protected final Set<String> seen = Sets.newHashSet();
 
+	private String sid;
+
+	private SearchClient privateSearchClient;
+
 	/**
 	 * Process the given object.
 	 * <p>
@@ -85,7 +89,7 @@ protected void walkAggregation(final ObjectType aggregation,
 			throw new IllegalStateException(
 					"AggregationTreeWalkers must be initialized with a repository before use.");
 		
-		final Response response = getRepository().getPublicSearchClient()
+		final Response response = getSearchClient(isPublic(aggregation))
 				.listAggregation(
 						aggregation.getGeneric().getGenerated()
 								.getTextgridUri().getValue());
@@ -100,6 +104,26 @@ protected void walkAggregation(final ObjectType aggregation,
 
 	}
 
+	/**
+	 * Returns whether the object identified by the argument is public.
+	 */
+	protected static boolean isPublic(final ObjectType object) {
+		final String availability = object.getGeneric().getGenerated()
+				.getAvailability();
+		return (availability != null && availability.contains("public"));
+	}
+
+	protected SearchClient getSearchClient(final boolean isPublic) {
+		if (isPublic)
+			return getRepository().getPublicSearchClient();
+		else {
+			if (privateSearchClient == null)
+				privateSearchClient = getRepository()
+						.createPrivateSearchClient(getSid());
+			return privateSearchClient;
+		}
+	}
+
 	/**
 	 * Called by {@link #walkAggregation(ObjectType, boolean)} when the
 	 * aggregation contains entries for which there is no metadata included.
@@ -119,4 +143,13 @@ public ITextGridRep getRepository() {
 	public void setRepository(final ITextGridRep repository) {
 		this.repository = repository;
 	}
+
+	public String getSid() {
+		return sid;
+	}
+
+	public void setSid(final String sid) {
+		this.sid = sid;
+		this.privateSearchClient = null;
+	}
 }
diff --git a/src/main/java/info/textgrid/services/aggregator/ITextGridRep.java b/src/main/java/info/textgrid/services/aggregator/ITextGridRep.java
index 1dd50e6c91805a4b67ee93708abdbde0b030ec82..879841094d11bfe44fae0ab35012749b54ee7115 100644
--- a/src/main/java/info/textgrid/services/aggregator/ITextGridRep.java
+++ b/src/main/java/info/textgrid/services/aggregator/ITextGridRep.java
@@ -34,6 +34,8 @@ public abstract InputStream getContent(final URI uri, String sid)
 	public abstract TGOSupplier<InputStream> read(final URI uri, final String sid)
 			throws WebApplicationException;
 
+	public abstract SearchClient createPrivateSearchClient(final String sid);
+
 	public interface TGOSupplier<T> extends InputSupplier<T> {
 		public ObjectType getMetadata();
 	}
diff --git a/src/main/java/info/textgrid/services/aggregator/TextGridRepProvider.java b/src/main/java/info/textgrid/services/aggregator/TextGridRepProvider.java
index 2740804767af733a57835af83f99c22b30eba598..2757986b9371a59caffbd58f330a28bea5e59717 100644
--- a/src/main/java/info/textgrid/services/aggregator/TextGridRepProvider.java
+++ b/src/main/java/info/textgrid/services/aggregator/TextGridRepProvider.java
@@ -37,6 +37,7 @@ public class TextGridRepProvider implements ITextGridRep {
 	private TGCrudService crud;
 	private SearchClient publicSearchClient;
 	private String CONF_ENDPOINT = "https://www.textgridlab.org/1.0/confserv";
+
 	public String getCONF_ENDPOINT() {
 		return CONF_ENDPOINT;
 	}
@@ -66,19 +67,25 @@ public String getConfValue(final String key) throws WebApplicationException {
 	@Override
 	public TGCrudService getCRUDService() {
 		if (crud == null) {
-			final URL wsdl = TGCrudService_Service.class.getResource("/wsdl/TGCrudService.wsdl");
-			final TGCrudService_Service tgCrudService_Service = new TGCrudService_Service(wsdl);
-			final TGCrudService _crud = tgCrudService_Service.getTGCrudPort(new MTOMFeature());
+			final URL wsdl = TGCrudService_Service.class
+					.getResource("/wsdl/TGCrudService.wsdl");
+			final TGCrudService_Service tgCrudService_Service = new TGCrudService_Service(
+					wsdl);
+			final TGCrudService _crud = tgCrudService_Service
+					.getTGCrudPort(new MTOMFeature());
 			final BindingProvider bp = (BindingProvider) _crud;
 			final Map<String, Object> requestContext = bp.getRequestContext();
-			requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, getConfValue(ConfservClientConstants.TG_CRUD));
+			requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
+					getConfValue(ConfservClientConstants.TG_CRUD));
 			crud = _crud;
 		}
 		return crud;
 	}
 
 	@Override
-	public InputStream getContent(final URI uri, final String sid) throws ObjectNotFoundFault, MetadataParseFault, IoFault, ProtocolNotImplementedFault, AuthFault, IOException {
+	public InputStream getContent(final URI uri, final String sid)
+			throws ObjectNotFoundFault, MetadataParseFault, IoFault,
+			ProtocolNotImplementedFault, AuthFault, IOException {
 		final TGCrudService crudService = getCRUDService();
 		final Holder<MetadataContainerType> mdHolder = new Holder<MetadataContainerType>();
 		final Holder<DataHandler> dHolder = new Holder<DataHandler>();
@@ -87,14 +94,14 @@ public InputStream getContent(final URI uri, final String sid) throws ObjectNotF
 	}
 
 	@Override
-	public TGOSupplier<InputStream> read(final URI uri, final String sid) throws WebApplicationException {
+	public TGOSupplier<InputStream> read(final URI uri, final String sid)
+			throws WebApplicationException {
 		final TGCrudService crudService = getCRUDService();
 		final Holder<MetadataContainerType> mdHolder = new Holder<MetadataContainerType>();
 		final Holder<DataHandler> dHolder = new Holder<DataHandler>();
 		try {
 			crudService.read(sid, null, uri.toString(), mdHolder, dHolder);
 
-
 			return new TGOSupplier<InputStream>() {
 
 				@Override
@@ -121,17 +128,36 @@ public ObjectType getMetadata() {
 	}
 
 	@Override
-	public InputStream getContent(final URI uri) throws ObjectNotFoundFault, MetadataParseFault, IoFault, ProtocolNotImplementedFault, AuthFault, IOException {
+	public InputStream getContent(final URI uri) throws ObjectNotFoundFault,
+			MetadataParseFault, IoFault, ProtocolNotImplementedFault,
+			AuthFault, IOException {
 		return getContent(uri, null);
 	}
 
 	@Override
 	public SearchClient getPublicSearchClient() {
 		if (publicSearchClient == null)
-			publicSearchClient = new SearchClient(getConfValue(ConfservClientConstants.TG_SEARCH_PUBLIC));
+			publicSearchClient = new SearchClient(
+					getConfValue(ConfservClientConstants.TG_SEARCH_PUBLIC));
 		return publicSearchClient;
 	}
 
+	/**
+	 * Creates a search client for the non-public repository, readily
+	 * initialized with the given session id. Note that this must be cached by
+	 * the client.
+	 * 
+	 * @param sid
+	 * @return
+	 */
+	@Override
+	public SearchClient createPrivateSearchClient(final String sid) {
+		final SearchClient client = new SearchClient(
+				getConfValue(ConfservClientConstants.TG_SEARCH));
+		client.setSid(sid);
+		return client;
+	}
+
 	public static ITextGridRep getInstance() {
 		return instance;
 	}
diff --git a/src/main/java/info/textgrid/services/aggregator/epub/EPUB.java b/src/main/java/info/textgrid/services/aggregator/epub/EPUB.java
index b8cc42648643e67f038045da58882c0c1afb0c8a..d4c67a42297bc2acf785873a34c5e21f46283f70 100644
--- a/src/main/java/info/textgrid/services/aggregator/epub/EPUB.java
+++ b/src/main/java/info/textgrid/services/aggregator/epub/EPUB.java
@@ -68,13 +68,14 @@ public EPUB(final ITextGridRep repository) {
 	@Path(value = "/{object}")
 	@Produces(value = "application/epub+zip")
 	public Response get(@PathParam("object") final URI uri,
-			@QueryParam("stylesheet") final URI xsluri)
+			@QueryParam("stylesheet") final URI xsluri,
+			@QueryParam("sid") final String sid)
 			throws ObjectNotFoundFault, MetadataParseFault, IoFault, AuthFault,
 			ProtocolNotImplementedFault {
 		logger.fine("EPUB called for root object: " + uri);
 		final TGCrudService crud = repository.getCRUDService();
 		try {
-			final MetadataContainerType container = crud.readMetadata(null,
+			final MetadataContainerType container = crud.readMetadata(sid,
 					null, uri.toString());
 			final ObjectType rootObject = container.getObject();
 			final String mimeType = rootObject.getGeneric().getProvided()
@@ -95,7 +96,7 @@ public Response get(@PathParam("object") final URI uri,
 			if (aggregation) {
 				// First, use the aggregator to create a TEI corpus file to build on
 				final TEICorpusSerializer corpusSerializer = new TEICorpusSerializer(
-						rootObject, true);
+						rootObject, true, sid);
 				final FileOutputStream corpusOutput = new FileOutputStream(corpus);
 				corpusSerializer.write(corpusOutput);
 				corpusOutput.close();
diff --git a/src/main/java/info/textgrid/services/aggregator/teicorpus/TEICorpus.java b/src/main/java/info/textgrid/services/aggregator/teicorpus/TEICorpus.java
index 5817b5abae44f945278f80e980bfa33a24962393..e7552f0aa2028f6f838fd0fc5ee209039b6525cd 100644
--- a/src/main/java/info/textgrid/services/aggregator/teicorpus/TEICorpus.java
+++ b/src/main/java/info/textgrid/services/aggregator/teicorpus/TEICorpus.java
@@ -6,6 +6,7 @@
 import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.MetadataParseFault;
 import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.ObjectNotFoundFault;
 import info.textgrid.namespaces.middleware.tgcrud.services.tgcrudservice.TGCrudService;
+import info.textgrid.services.aggregator.AggregationTreeWalker;
 import info.textgrid.services.aggregator.ITextGridRep;
 import info.textgrid.services.aggregator.RESTUtils;
 
@@ -67,16 +68,18 @@ public TEICorpus(final ITextGridRep repository) {
 	@Produces("text/xml")
 	public Response get(@PathParam("aggregation") final URI uri,
 			@QueryParam("attach") @DefaultValue("true") final boolean attach,
-			@QueryParam("flat") @DefaultValue("false") final boolean flat)
+			@QueryParam("flat") @DefaultValue("false") final boolean flat,
+			@QueryParam("sid") final String sid)
 					throws URISyntaxException {
 		logger.fine("TEIcorpus called for root aggregation: " + uri);
 		final TGCrudService crud = repository.getCRUDService();
 		logger.finest("Yo, clients are there.");
 		try {
-			final MetadataContainerType rootAggregationMetadata = crud.readMetadata(null, null, uri.toString());
+			final MetadataContainerType rootAggregationMetadata = crud
+					.readMetadata(sid, null, uri.toString());
 			logger.finer("CRUD request for root aggregation successful");
-			final TEICorpusSerializer serializer = new TEICorpusSerializer(
-					rootAggregationMetadata.getObject(), flat);
+			final AggregationTreeWalker serializer = new TEICorpusSerializer(
+					rootAggregationMetadata.getObject(), flat, sid);
 			final String format = rootAggregationMetadata.getObject().getGeneric().getProvided().getFormat();
 			if (!format.contains("aggregation")) {
 				logger.log(Level.SEVERE, "The requested object {0} is a {1}, not an aggregation, and thus cannot be aggregated.", new Object[] {uri,format});
diff --git a/src/main/java/info/textgrid/services/aggregator/teicorpus/TEICorpusSerializer.java b/src/main/java/info/textgrid/services/aggregator/teicorpus/TEICorpusSerializer.java
index b29e2ba435ee84e367843081afec11494d3b8c5e..ab45686639a3e73fd2ff103d53153893aa358869 100644
--- a/src/main/java/info/textgrid/services/aggregator/teicorpus/TEICorpusSerializer.java
+++ b/src/main/java/info/textgrid/services/aggregator/teicorpus/TEICorpusSerializer.java
@@ -61,7 +61,6 @@ public boolean accept(final XMLEvent event) {
 	private boolean handled;
 	private boolean flat;
 	private int level = 0;
-	
 	private static String toString(final ObjectType object) {
 		return Joiner.on(" / ").join(object.getGeneric().getProvided().getTitle()) + " (" + object.getGeneric().getGenerated().getTextgridUri().getValue() + ", " +
 			object.getGeneric().getProvided().getFormat() + ")";
@@ -74,10 +73,12 @@ public TEICorpusSerializer(final ObjectType object)
 		logger.info("Starting TEIcorpus serialization for " + toString(object));
 	}
 
-	public TEICorpusSerializer(final ObjectType object, final boolean flat)
+	public TEICorpusSerializer(final ObjectType object, final boolean flat,
+			final String sid)
 			throws ObjectNotFoundFault, MetadataParseFault, IoFault, AuthFault {
 		this(object);
 		this.flat = flat;
+		this.setSid(sid);
 	}
 
 	@Override
@@ -216,7 +217,7 @@ protected void walkXML(final ObjectType object) {
 		final Holder<DataHandler> dhHolder = new Holder<DataHandler>();
 		try {
 			getRepository().getCRUDService().read(
-					"",
+					getSid(),
 					"",
 					object.getGeneric().getGenerated().getTextgridUri()
 							.getValue(), mdHolder,
diff --git a/src/test/java/info/textgrid/services/aggregator/EPUBTest.java b/src/test/java/info/textgrid/services/aggregator/EPUBTest.java
index 413d7f9fbdc1338cddc9c7038f90c645c6036827..39a2a940554708217fbf7ed419dff4f4ac096d2c 100644
--- a/src/test/java/info/textgrid/services/aggregator/EPUBTest.java
+++ b/src/test/java/info/textgrid/services/aggregator/EPUBTest.java
@@ -19,7 +19,8 @@ public class EPUBTest {
 	public void testGet() throws ObjectNotFoundFault, MetadataParseFault,
 			IoFault, AuthFault, ProtocolNotImplementedFault {
 		final EPUB epub = new EPUB(TextGridRepProvider.getInstance());
-		final Response response = epub.get(URI.create("textgrid:jfst.0"), null);
+		final Response response = epub.get(URI.create("textgrid:jfst.0"), null,
+				null);
 	}
 
 }
diff --git a/src/test/java/info/textgrid/services/aggregator/teicorpus/TEICorpusTest.java b/src/test/java/info/textgrid/services/aggregator/teicorpus/TEICorpusTest.java
index 56e1c1c1fff6bbd69fc42010d6750e0b95a9093c..ddc4ef762833eda989d7603044162cb6c91cb505 100644
--- a/src/test/java/info/textgrid/services/aggregator/teicorpus/TEICorpusTest.java
+++ b/src/test/java/info/textgrid/services/aggregator/teicorpus/TEICorpusTest.java
@@ -1,7 +1,6 @@
 package info.textgrid.services.aggregator.teicorpus;
 
 import info.textgrid.services.aggregator.TextGridRepProvider;
-import info.textgrid.services.aggregator.teicorpus.TEICorpus;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -31,7 +30,7 @@ public void setUp() throws Exception {
 	@Test(expected = WebApplicationException.class)
 	public void testGet404() throws URISyntaxException {
 		final Response response = teiCorpus.get(URI.create("textgrid:doesnotexist"),
-				true, false);
+ true, false, null);
 		Assert.assertEquals(404, response.getStatus());
 	}
 
@@ -39,7 +38,7 @@ public void testGet404() throws URISyntaxException {
 	public void testGet() throws URISyntaxException, WebApplicationException,
 	IOException {
 		final Response response = teiCorpus.get(URI.create("textgrid:jmzg.0"), true,
-				false);
+ false, null);
 		final Object entity = response.getEntity();
 		final ByteArrayOutputStream output = new ByteArrayOutputStream();
 		((StreamingOutput) entity).write(output);