diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestValid.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestValid.java
index c557d1f12a8322bafddc6ae7ea3f51587ebb02e2..dca6e2944319202d77075d36eb559da31c6c7e81 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestValid.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestValid.java
@@ -314,6 +314,19 @@ class CommandTestValid extends AbstractDssCommand<CommandTestValid.CommandTestVa
                 {
                 }
 
+                @Override
+                public InputStream getFileFromSessionWorkspace(String filePath)
+                        throws IOExceptionUnchecked
+                {
+                    return null;
+                }
+
+                @Override
+                public void getFileFromSessionWorkspace(String filePath, File localFile)
+                        throws IOExceptionUnchecked
+                {
+                }
+
                 @Override
                 public boolean deleteSessionWorkspaceFile(String path)
                 {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDssComponent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDssComponent.java
index cd6d91526ff13326364cb29ef8de26fd74550acd..6ea58ccdaebec45b5a3332c650d60ce1fbc93911 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDssComponent.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDssComponent.java
@@ -89,8 +89,7 @@ public interface IDssComponent
      * Uploads a file to the session workspace.
      * 
      * @param filePath The path (directory and name) of the file to upload.
-     * @param inputStream The data of the file to upload.
-     * 
+     * @param inputStream The content of the file to upload.
      * @throws IOExceptionUnchecked If the file transfer fails.
      */
     public void putFileToSessionWorkspace(String filePath, InputStream inputStream)
@@ -101,19 +100,37 @@ public interface IDssComponent
      * 
      * @param directory The directory in the session workspace where the file should be uploaded.
      * @param file The file to upload.
-     * 
-     * @throws IOExceptionUnchecked If the file transfer fails.
+     * @throws IOExceptionUnchecked If the file cannot be written.
      */
     public void putFileToSessionWorkspace(String directory, File file)
             throws IOExceptionUnchecked;
 
+    /**
+     * Downloads a file from the session workspace.
+     * 
+     * @param filePath The path (directory and name) of the file to download.
+     * @return outputStream The content of the file to download.
+     * @throws IOExceptionUnchecked If the file does not exist, is a directory or cannot be opened.
+     */
+    public InputStream getFileFromSessionWorkspace(String filePath) throws IOExceptionUnchecked;
+
+    /**
+     * Downloads a file from the session workspace.
+     * 
+     * @param filePath The path (directory and name) of the file to download.
+     * @param localFile The local file to write the file from the session workspace to.
+     * @throws IOExceptionUnchecked If the file does not exist.
+     */
+    public void getFileFromSessionWorkspace(String filePath, File localFile)
+            throws IOExceptionUnchecked;
+
     /**
      * Delete a file or directory in the session workspace.
      * 
      * @return <code>true</code> if the <var>path</var> doesn't exist anymore.
      */
     public boolean deleteSessionWorkspaceFile(String path);
-    
+
     /**
      * Validate a data set.
      * 
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
index 196155ad996b066856883abc6ed380a77e662818..48b34ecc22f1cd356135ed873567529ee5fa0e45 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
@@ -20,6 +20,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
@@ -30,6 +31,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.io.IOUtils;
 import org.python.core.Py;
 import org.python.core.PyException;
 import org.springframework.remoting.RemoteAccessException;
@@ -59,6 +61,8 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.validation.ValidationE
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.validation.ValidationScriptRunner;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 
+import de.schlichtherle.io.FileOutputStream;
+
 /**
  * Implementation of the IDssComponent interface. It is a facade for interacting with openBIS and
  * multiple DSS servers.
@@ -236,6 +240,19 @@ public class DssComponent implements IDssComponent
         state.putFileToSessionWorkspace(directory, file);
     }
 
+    @Override
+    public InputStream getFileFromSessionWorkspace(String filePath) throws IOExceptionUnchecked
+    {
+        return state.getFileFromSessionWorkspace(filePath);
+    }
+
+    @Override
+    public void getFileFromSessionWorkspace(String filePath, File localFile)
+            throws IOExceptionUnchecked
+    {
+        state.getFileFromSessionWorkspace(filePath, localFile);
+    }
+
     @Override
     public boolean deleteSessionWorkspaceFile(String path)
     {
@@ -307,6 +324,19 @@ abstract class AbstractDssComponentState implements IDssComponent
         throw new IllegalStateException("Please log in");
     }
 
+    @Override
+    public InputStream getFileFromSessionWorkspace(String filePath) throws IOExceptionUnchecked
+    {
+        throw new IllegalStateException("Please log in");
+    }
+
+    @Override
+    public void getFileFromSessionWorkspace(String filePath, File localFile)
+            throws IOExceptionUnchecked
+    {
+        throw new IllegalStateException("Please log in");
+    }
+
     @Override
     public boolean deleteSessionWorkspaceFile(String path)
     {
@@ -477,25 +507,47 @@ class AuthenticatedState extends AbstractDssComponentState
     {
         final IDssServiceRpcGeneric dssService = getServiceForPutDataStore();
         final String filePath = directory + "/" + file.getName();
-        InputStream inputStream = null;
+        InputStream istream = null;
         try
         {
-            inputStream = new FileInputStream(file);
-            dssService.putFileToSessionWorkspace(sessionToken, filePath, inputStream);
+            istream = new FileInputStream(file);
+            dssService.putFileToSessionWorkspace(sessionToken, filePath, istream);
         } catch (IOException ex)
         {
             throw CheckedExceptionTunnel.wrapIfNecessary(ex);
         } finally
         {
-            if (inputStream != null)
-            {
-                try
-                {
-                    inputStream.close();
-                } catch (IOException ex)
-                {
-                }
-            }
+            IOUtils.closeQuietly(istream);
+        }
+    }
+
+    @Override
+    public InputStream getFileFromSessionWorkspace(String filePath) throws IOExceptionUnchecked
+    {
+        final IDssServiceRpcGeneric dssService = getServiceForPutDataStore();
+        return dssService.getFileFromSessionWorkspace(sessionToken, filePath);
+    }
+
+    @Override
+    public void getFileFromSessionWorkspace(String filePath, File localFile)
+            throws IOExceptionUnchecked
+    {
+        final IDssServiceRpcGeneric dssService = getServiceForPutDataStore();
+        final InputStream istream = dssService.getFileFromSessionWorkspace(sessionToken, filePath);
+        OutputStream ostream = null;
+        try
+        {
+            ostream = new FileOutputStream(localFile);
+            IOUtils.copyLarge(istream, ostream);
+            ostream.close();
+        } catch (IOException ex)
+        {
+            localFile.delete();
+            throw CheckedExceptionTunnel.wrapIfNecessary(ex);
+        } finally
+        {
+            IOUtils.closeQuietly(istream);
+            IOUtils.closeQuietly(ostream);
         }
     }
 
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java
index 0f67590039eff3c81ec0bcc39117ccd3b065a74f..2a2cea1cc1c703cae6e6dcd1e785804e39ca3161 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java
@@ -17,6 +17,8 @@
 package ch.systemsx.cisd.openbis.dss.generic.server.api.v1;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -226,6 +228,28 @@ public class DssServiceRpcGeneric extends AbstractDssServiceRpc<IDssServiceRpcGe
         }
     }
 
+    @Override
+    public InputStream getFileFromSessionWorkspace(String sessionToken, String filePath)
+            throws IOExceptionUnchecked
+    {
+        getOpenBISService().checkSession(sessionToken);
+        if (filePath.contains("../"))
+        {
+            throw new IOExceptionUnchecked("filePath must not contain '../'");
+        }
+        final File workspaceDir =
+                new SessionWorkspaceProvider(sessionWorkspaceRootDirectory, sessionToken)
+                        .getSessionWorkspace();
+        final File file = new File(workspaceDir, filePath);
+        try
+        {
+            return new FileInputStream(file);
+        } catch (FileNotFoundException ex)
+        {
+            throw new IOExceptionUnchecked(ex);
+        }
+    }
+
     @Override
     public boolean deleteSessionWorkspaceFile(String sessionToken, String path)
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java
index 8b4341b21dc390874085b50d78bb26cab3ec0887..8ae2e89f244a5351375af7f23b7d925631b3ee71 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java
@@ -117,6 +117,15 @@ public class DssServiceRpcGenericLogger extends AbstractServerLogger implements
         logTracking(sessionToken, "put_file_to_session_workspace", "FILE_PATH(%s)", filePath);
     }
 
+    @Override
+    @DataSetAccessGuard
+    public InputStream getFileFromSessionWorkspace(String sessionToken, String filePath)
+            throws IOExceptionUnchecked
+    {
+        logAccess(sessionToken, "get_file_from_session_workspace", "FILE_PATH(%s)", filePath);
+        return null;
+    }
+
     @Override
     public boolean deleteSessionWorkspaceFile(String sessionToken, String path)
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java
index 122fd080dcff501cc4565d61a433704209fdc815..8460b00c32ebebc41dbe3f74b3727b25ca0335c8 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java
@@ -46,7 +46,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
     @DataSetAccessGuard
     public FileInfoDssDTO[] listFilesForDataSet(
             String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class) DataSetFileDTO fileOrFolder)
+            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class)
+            DataSetFileDTO fileOrFolder)
             throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -62,7 +63,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
     @Deprecated
     public InputStream getFileForDataSet(
             String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class) DataSetFileDTO fileOrFolder)
+            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class)
+            DataSetFileDTO fileOrFolder)
             throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -78,9 +80,10 @@ public interface IDssServiceRpcGeneric extends IRpcService
     @DataSetAccessGuard
     public String getDownloadUrlForFileForDataSet(
             String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class) DataSetFileDTO fileOrFolder)
-                    throws IOExceptionUnchecked, IllegalArgumentException;
-    
+            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class)
+            DataSetFileDTO fileOrFolder)
+            throws IOExceptionUnchecked, IllegalArgumentException;
+
     /**
      * Get an array of FileInfoDss objects that describe the file-system structure of the data set.
      * 
@@ -93,7 +96,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
      */
     @DataSetAccessGuard
     public FileInfoDssDTO[] listFilesForDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class) String dataSetCode,
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
             String path, boolean isRecursive) throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -109,7 +113,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
     @DataSetAccessGuard
     @Deprecated
     public InputStream getFileForDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class) String dataSetCode,
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
             String path) throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -125,9 +130,10 @@ public interface IDssServiceRpcGeneric extends IRpcService
      */
     @DataSetAccessGuard
     public String getDownloadUrlForFileForDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class) String dataSetCode,
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
             String path) throws IOExceptionUnchecked, IllegalArgumentException;
-    
+
     /**
      * Upload a new data set to the DSS.
      * 
@@ -140,7 +146,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
      */
     @DataSetAccessGuard
     public String putDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = NewDataSetPredicate.class) NewDataSetDTO newDataset,
+            @AuthorizationGuard(guardClass = NewDataSetPredicate.class)
+            NewDataSetDTO newDataset,
             InputStream inputStream) throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -149,20 +156,29 @@ public interface IDssServiceRpcGeneric extends IRpcService
      * @param sessionToken The session token.
      * @param filePath The file path (including the sub-directory) to upload the file to.
      * @param inputStream An input stream on the file to upload.
-     * @throws IOExceptionUnchecked Thrown if an IOException.
+     * @throws IOExceptionUnchecked Thrown if because <var>filePath</var> does not exist.
      */
-    @DataSetAccessGuard
     public void putFileToSessionWorkspace(String sessionToken, String filePath,
             InputStream inputStream) throws IOExceptionUnchecked;
 
+    /**
+     * Download a new file from the user's session workspace.
+     * 
+     * @param sessionToken The session token.
+     * @param filePath The file path (including the sub-directory) to upload the file to.
+     * @return The output stream containing the file content.
+     * @throws IOExceptionUnchecked Thrown if an IOException occurs.
+     */
+    public InputStream getFileFromSessionWorkspace(String sessionToken, String filePath)
+            throws IOExceptionUnchecked;
+
     /**
      * Delete a file or directory in the session workspace.
      * 
      * @return <code>true</code> if the <var>path</var> doesn't exist anymore.
      */
-    @DataSetAccessGuard
     public boolean deleteSessionWorkspaceFile(String sessionToken, String path);
-    
+
     /**
      * Get a path to the data set. This can be used by clients that run on the same machine as the
      * DSS for more efficient access to a data set.
@@ -182,8 +198,10 @@ public interface IDssServiceRpcGeneric extends IRpcService
      */
     @DataSetAccessGuard(releaseDataSetLocks = false)
     public String getPathToDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class) String dataSetCode,
-            String overrideStoreRootPathOrNull) throws IOExceptionUnchecked, IllegalArgumentException;
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
+            String overrideStoreRootPathOrNull) throws IOExceptionUnchecked,
+            IllegalArgumentException;
 
     /**
      * Get the validation script for the specified data set type.
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
index 6d1e0449259b5a4755ec916918376a2bec7e87f0..32fb85b442ab275df33d1db0eec04d04bc6ea428 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
@@ -670,6 +670,13 @@ public class DssComponentTest extends AbstractFileSystemTestCase
             return false;
         }
 
+        @Override
+        public InputStream getFileFromSessionWorkspace(String sessionToken, String filePath)
+                throws IOExceptionUnchecked
+        {
+            return null;
+        }
+
     }
 
     private class MockDssServiceRpcV1_1 extends MockDssServiceRpcV1_0