You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by mo...@apache.org on 2015/08/21 23:20:21 UTC

incubator-zeppelin git commit: Configurable Origins and small configuration fixes

Repository: incubator-zeppelin
Updated Branches:
  refs/heads/master acda3de9d -> 703b47f79


Configurable Origins and small configuration fixes

This makes it configurable to specify multiple origins as allowed (default only local origin is allowed). Wildcard origin will not be supported as it is a security vulnerability.
It adds a compatibility check in configuration for windows paths.
Upgrades servlet config to add httponly and secure which will secure session cookies if used.

Author: joelz <dj...@gmail.com>
Author: djoelz <jo...@microsoft.com>

Closes #235 from djoelz/master and squashes the following commits:

989f1e0 [joelz] Retrying build as it seems ZeppelinIT failed for not reason.
625b54e [joelz] Fixing unit test that reads from a file but initializes to a default value and hence the configuration is present.
e9d8384 [joelz] Retrying due to git download issue with build
2887f0d [joelz] Renaming tests to singular name so plugin can detect and run
9260d5d [joelz] Fixing adding the origin header for get and post tests.
b7bb7bf [joelz] Fixing Styling
b2b418a [joelz] Fixing cross origin bug for rest calls that allow a malicious user to issue requests from a site other than the zeppelin server. Adding unit tests and a dependency to mockito to the server project (please comment if that is ok or if there is another preferred mocking framework). Also upgrading the servelet version from 2.5 to 3.0 as this also fixes a security vulnerability with respect to httonly cookies.
4ae9129 [joelz] Fixing null reference
3795de7 [joelz] Fixing cross origin bug for rest calls that allow a malicious user to issue requests from a site other than the zeppelin server. Adding unit tests and a dependency to mockito to the server project (please comment if that is ok or if there is another preferred mocking framework). Also upgrading the servelet version from 2.5 to 3.0 as this also fixes a security vulnerability with respect to httonly cookies.
bcb1ac1 [joelz] Fixing cross origin bug for rest calls that allow a malicious user to issue requests from a site other than the zeppelin server. Adding unit tests and a dependency to mockito to the server project (please comment if that is ok or if there is another preferred mocking framework). Also upgrading the servelet version from 2.5 to 3.0 as this also fixes a security vulnerability with respect to httonly cookies.
3d6ce2e [joelz] Fixing cross origin bug for rest calls that allow a malicious user to issue requests from a site other than the zeppelin server. Adding unit tests and a dependency to mockito to the server project (please comment if that is ok or if there is another preferred mocking framework). Also upgrading the servelet version from 2.5 to 3.0 as this also fixes a security vulnerability with respect to httonly cookies.
1f851c0 [joelz] Fixing cross origin bug for rest calls that allow a malicious user to issue requests from a site other than the zeppelin server. Adding unit tests and a dependency to mockito to the server project (please comment if that is ok or if there is another preferred mocking framework). Also upgrading the servelet version from 2.5 to 3.0 as this also fixes a security vulnerability with respect to httonly cookies.
7ecf7e9 [joelz] Merge branch 'master' of https://github.com/djoelz/incubator-zeppelin
faa6204 [joelz] Merge branch 'apache-master'
52eb1bd [joelz] Merge branch 'master' of https://github.com/apache/incubator-zeppelin into apache-master
5ff1a47 [joelz] Merge branch 'masterOrigin'
47902a6 [joelz] Fixing cross origin bug for rest calls that allow a malicious user to issue requests from a site other than the zeppelin server. Adding unit tests and a dependency to mockito to the server project (please comment if that is ok or if there is another preferred mocking framework). Also upgrading the servelet version from 2.5 to 3.0 as this also fixes a security vulnerability with respect to httonly cookies.
a00adc2 [djoelz] Merge pull request #1 from apache/master
df324de [joelz] Fixing cross origin bug for rest calls that allow a malicious user to issue requests from a site other than the zeppelin server. Adding unit tests and a dependency to mockito to the server project (please comment if that is ok or if there is another preferred mocking framework). Also upgrading the servelet version from 2.5 to 3.0 as this also fixes a security vulnerability with respect to httonly cookies.
cecbab8 [joelz] Fixing cross origin bug for rest calls that allow a malicious user to issue requests from a site other than the zeppelin server. Adding unit tests and a dependency to mockito to the server project (please comment if that is ok or if there is another preferred mocking framework). Also upgrading the servelet version from 2.5 to 3.0 as this also fixes a security vulnerability with respect to httonly cookies.
61e857d [joelz] Fixing Rest request lack of Origin validation bug, Added tests that use Mockito (unit test framework) and forces the servlet to use version 3.0 instead of 2.5
08ff369 [djoelz] unecessary file
013f22d [joelz] Fixing issue with ZEPPELIN-173: Zeppelin websocket server is vulnerable to Cross-Site WebSocket Hijacking
ea54b55 [joelz] Fixing issue with ZEPPELIN-173: Zeppelin websocket server is vulnerable to Cross-Site WebSocket Hijacking


Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/703b47f7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/703b47f7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/703b47f7

Branch: refs/heads/master
Commit: 703b47f79bc5b889199fb6dbaac559aed74df0e1
Parents: acda3de
Author: joelz <dj...@gmail.com>
Authored: Fri Aug 21 12:47:13 2015 -0700
Committer: Lee moon soo <mo...@apache.org>
Committed: Fri Aug 21 14:20:09 2015 -0700

----------------------------------------------------------------------
 conf/zeppelin-site.xml.template                 |   6 +
 .../org/apache/zeppelin/server/CorsFilter.java  |  17 +-
 .../apache/zeppelin/socket/NotebookServer.java  |  18 +-
 .../apache/zeppelin/utils/SecurityUtils.java    |  46 ++++++
 .../zeppelin/rest/AbstractTestRestApi.java      |   4 +-
 .../zeppelin/rest/ZeppelinRestApiTest.java      |   3 +-
 .../zeppelin/security/SecurityUtilsTest.java    |  90 ++++++++++
 .../apache/zeppelin/server/CorsFilterTest.java  |  94 +++++++++++
 .../apache/zeppelin/server/CorsFilterTests.java |  95 -----------
 .../zeppelin/socket/NotebookServerTest.java     |  52 ++++++
 .../zeppelin/socket/NotebookServerTests.java    |  50 ------
 .../src/test/resources/zeppelin-site-star.xml   | 163 +++++++++++++++++++
 .../src/test/resources/zeppelin-site.xml        | 163 +++++++++++++++++++
 .../zeppelin/conf/ZeppelinConfiguration.java    |  30 +++-
 .../conf/ZeppelinConfigurationTest.java         |  73 +++++++++
 .../src/test/resources/test-zeppelin-site1.xml  | 163 +++++++++++++++++++
 .../src/test/resources/test-zeppelin-site2.xml  | 163 +++++++++++++++++++
 .../src/test/resources/zeppelin-site.xml        | 158 ++++++++++++++++++
 18 files changed, 1216 insertions(+), 172 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/conf/zeppelin-site.xml.template
----------------------------------------------------------------------
diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template
index 57d1b23..5d3b97d 100644
--- a/conf/zeppelin-site.xml.template
+++ b/conf/zeppelin-site.xml.template
@@ -154,5 +154,11 @@
 </property>
 -->
 
+<property>
+  <name>zeppelin.server.allowed.origins</name>
+  <value>*</value>
+  <description>Allowed sources for REST and WebSocket requests (i.e. http://onehost:8080,http://otherhost.com). If you leave * you are vulnerable to https://issues.apache.org/jira/browse/ZEPPELIN-173</description>
+</property>
+
 </configuration>
 

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/main/java/org/apache/zeppelin/server/CorsFilter.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/server/CorsFilter.java b/zeppelin-server/src/main/java/org/apache/zeppelin/server/CorsFilter.java
index c2a137f..0e39242 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/server/CorsFilter.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/server/CorsFilter.java
@@ -17,9 +17,14 @@
 
 package org.apache.zeppelin.server;
 
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.utils.SecurityUtils;
+
 import java.io.IOException;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.text.DateFormat;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Locale;
 
@@ -41,11 +46,15 @@ public class CorsFilter implements Filter {
   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
       throws IOException, ServletException {
-    String sourceHost = request.getServerName();
-    String currentHost = java.net.InetAddress.getLocalHost().getHostName();
+    String sourceHost = ((HttpServletRequest) request).getHeader("Origin");
     String origin = "";
-    if (currentHost.equals(sourceHost) || "localhost".equals(sourceHost)) {
-      origin = ((HttpServletRequest) request).getHeader("Origin");
+
+    try {
+      if (SecurityUtils.isValidOrigin(sourceHost, ZeppelinConfiguration.create())) {
+        origin = sourceHost;
+      }
+    } catch (URISyntaxException e) {
+      e.printStackTrace();
     }
 
     if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
index 5467fe6..df9c036 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
@@ -24,9 +24,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
 import javax.servlet.http.HttpServletRequest;
-
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
 import org.apache.zeppelin.display.AngularObject;
@@ -43,12 +41,12 @@ import org.apache.zeppelin.scheduler.Job.Status;
 import org.apache.zeppelin.scheduler.JobListener;
 import org.apache.zeppelin.server.ZeppelinServer;
 import org.apache.zeppelin.socket.Message.OP;
+import org.apache.zeppelin.utils.SecurityUtils;
 import org.eclipse.jetty.websocket.WebSocket;
 import org.eclipse.jetty.websocket.WebSocketServlet;
 import org.quartz.SchedulerException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import com.google.common.base.Strings;
 import com.google.gson.Gson;
 /**
@@ -69,24 +67,15 @@ public class NotebookServer extends WebSocketServlet implements
   }
   @Override
   public boolean checkOrigin(HttpServletRequest request, String origin) {
-    URI sourceUri = null;
-    String currentHost = null;
 
     try {
-      sourceUri = new URI(origin);
-      currentHost = java.net.InetAddress.getLocalHost().getHostName();
+      return SecurityUtils.isValidOrigin(origin, ZeppelinConfiguration.create());
     } catch (UnknownHostException e) {
       e.printStackTrace();
-    }
-    catch (URISyntaxException e) {
+    } catch (URISyntaxException e) {
       e.printStackTrace();
     }
 
-    String sourceHost = sourceUri.getHost();
-    if (currentHost.equals(sourceHost) || "localhost".equals(sourceHost)) {
-      return true;
-    }
-
     return false;
   }
 
@@ -300,6 +289,7 @@ public class NotebookServer extends WebSocketServlet implements
     List<Map<String, String>> notesInfo = new LinkedList<>();
     for (Note note : notes) {
       Map<String, String> info = new HashMap<>();
+
       if (hideHomeScreenNotebookFromList && note.id().equals(homescreenNotebookId)) {
         continue;
       }

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java
new file mode 100644
index 0000000..004f10d
--- /dev/null
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.zeppelin.utils;
+
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+
+/**
+ * Created by joelz on 8/19/15.
+ */
+public class SecurityUtils {
+  public static Boolean isValidOrigin(String sourceHost, ZeppelinConfiguration conf)
+      throws UnknownHostException, URISyntaxException {
+    if (sourceHost == null){
+      return false;
+    }
+
+    URI sourceHostUri = new URI(sourceHost);
+    String currentHost = java.net.InetAddress.getLocalHost().getHostName().toLowerCase();
+    if (currentHost.equals(sourceHostUri.getHost()) ||
+            "localhost".equals(sourceHostUri.getHost()) ||
+            conf.getAllowedOrigins().contains(sourceHost) ||
+            conf.getAllowedOrigins().contains("*")) {
+      return true;
+    }
+
+    return false;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java
index 393dc7b..aa395aa 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java
@@ -227,7 +227,8 @@ public abstract class AbstractTestRestApi {
     LOG.info("Connecting to {}", url + path);
     HttpClient httpClient = new HttpClient();
     GetMethod getMethod = new GetMethod(url + path);
-    httpClient.executeMethod(getMethod);
+    getMethod.addRequestHeader("Origin", "http://localhost:8080");
+            httpClient.executeMethod(getMethod);
     LOG.info("{} - {}", getMethod.getStatusCode(), getMethod.getStatusText());
     return getMethod;
   }
@@ -236,6 +237,7 @@ public abstract class AbstractTestRestApi {
     LOG.info("Connecting to {}", url + path);
     HttpClient httpClient = new HttpClient();
     PostMethod postMethod = new PostMethod(url + path);
+    postMethod.addRequestHeader("Origin", "http://localhost:8080");
     RequestEntity entity = new ByteArrayRequestEntity(body.getBytes("UTF-8"));
     postMethod.setRequestEntity(entity);
     httpClient.executeMethod(postMethod);

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
index 0da5e0d..4d52625 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
@@ -104,9 +104,10 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     // create note
     Note note = ZeppelinServer.notebook.createNote();
 
-    // check interpreter is bindded
+    // check interpreter is binded
     GetMethod get = httpGet("/notebook/interpreter/bind/"+note.id());
     assertThat(get, isAllowed());
+    get.addRequestHeader("Origin", "http://localhost");
     Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken<Map<String, Object>>(){}.getType());
     List<Map<String, String>> body = (List<Map<String, String>>) resp.get("body");
     assertTrue(0 < body.size());

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/test/java/org/apache/zeppelin/security/SecurityUtilsTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/security/SecurityUtilsTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/security/SecurityUtilsTest.java
new file mode 100644
index 0000000..df9f803
--- /dev/null
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/security/SecurityUtilsTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.zeppelin.security;
+
+import junit.framework.Assert;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.zeppelin.conf.ZeppelinConfiguration;
+import org.apache.zeppelin.utils.SecurityUtils;
+import org.junit.Test;
+
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+
+/**
+ * Created by joelz on 8/19/15.
+ */
+public class SecurityUtilsTest {
+    @Test
+    public void isInvalid() throws URISyntaxException, UnknownHostException {
+        Assert.assertFalse(SecurityUtils.isValidOrigin("http://127.0.1.1", ZeppelinConfiguration.create()));
+    }
+
+    @Test
+    public void isInvalidFromConfig() throws URISyntaxException, UnknownHostException, ConfigurationException {
+        Assert.assertFalse(
+                SecurityUtils.isValidOrigin("http://otherinvalidhost.com",
+                        new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml"))));
+    }
+
+    @Test
+    public void isLocalhost() throws URISyntaxException, UnknownHostException {
+        Assert.assertTrue(SecurityUtils.isValidOrigin("http://localhost", ZeppelinConfiguration.create()));
+    }
+
+    @Test
+    public void isLocalMachine() throws URISyntaxException, UnknownHostException {
+        Assert.assertTrue(SecurityUtils.isValidOrigin(
+                "http://" + java.net.InetAddress.getLocalHost().getHostName(),
+                ZeppelinConfiguration.create()));
+    }
+
+    @Test
+    public void isValidFromConfig() throws URISyntaxException, UnknownHostException, ConfigurationException {
+        Assert.assertTrue(
+                SecurityUtils.isValidOrigin("http://otherhost.com",
+                        new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml"))));
+    }
+
+    @Test
+    public void isValidFromStar() throws URISyntaxException, UnknownHostException, ConfigurationException {
+        Assert.assertTrue(
+                SecurityUtils.isValidOrigin("http://anyhost.com",
+                        new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site-star.xml"))));
+    }
+
+    @Test
+    public void nullOrigin() throws URISyntaxException, UnknownHostException, ConfigurationException {
+        Assert.assertFalse(
+                SecurityUtils.isValidOrigin(null,
+                        new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml"))));
+    }
+
+    @Test
+    public void emptyOrigin() throws URISyntaxException, UnknownHostException, ConfigurationException {
+        Assert.assertFalse(
+                SecurityUtils.isValidOrigin("",
+                        new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml"))));
+    }
+
+    @Test
+    public void notAURIOrigin() throws URISyntaxException, UnknownHostException, ConfigurationException {
+        Assert.assertFalse(
+                SecurityUtils.isValidOrigin("test123",
+                        new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml"))));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/test/java/org/apache/zeppelin/server/CorsFilterTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/server/CorsFilterTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/server/CorsFilterTest.java
new file mode 100644
index 0000000..a3057c8
--- /dev/null
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/server/CorsFilterTest.java
@@ -0,0 +1,94 @@
+/**
+ * Created by joelz on 8/6/15.
+ *
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.zeppelin.server;
+
+import org.apache.zeppelin.socket.TestHttpServletRequest;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.*;
+
+/**
+ * BASIC Cors rest api tests
+ *
+ *
+ * @author joelz
+ *
+ */
+public class CorsFilterTest {
+
+    public static String[] headers = new String[8];
+    public static Integer count = 0;
+
+    @Test
+    public void ValidCorsFilterTest() throws IOException, ServletException {
+        CorsFilter filter = new CorsFilter();
+        HttpServletResponse mockResponse = mock(HttpServletResponse.class);
+        FilterChain mockedFilterChain = mock(FilterChain.class);
+        TestHttpServletRequest mockRequest = mock(TestHttpServletRequest.class);
+        when(mockRequest.getHeader("Origin")).thenReturn("http://localhost:8080");
+        when(mockRequest.getMethod()).thenReturn("Empty");
+        when(mockRequest.getServerName()).thenReturn("localhost");
+        count = 0;
+
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+                headers[count] = invocationOnMock.getArguments()[1].toString();
+                count++;
+                return null;
+            }
+        }).when(mockResponse).addHeader(anyString(), anyString());
+
+        filter.doFilter(mockRequest, mockResponse, mockedFilterChain);
+        Assert.assertTrue(headers[0].equals("http://localhost:8080"));
+    }
+
+    @Test
+    public void InvalidCorsFilterTest() throws IOException, ServletException {
+        CorsFilter filter = new CorsFilter();
+        HttpServletResponse mockResponse = mock(HttpServletResponse.class);
+        FilterChain mockedFilterChain = mock(FilterChain.class);
+        TestHttpServletRequest mockRequest = mock(TestHttpServletRequest.class);
+        when(mockRequest.getHeader("Origin")).thenReturn("http://evillocalhost:8080");
+        when(mockRequest.getMethod()).thenReturn("Empty");
+        when(mockRequest.getServerName()).thenReturn("evillocalhost");
+
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+                headers[count] = invocationOnMock.getArguments()[1].toString();
+                count++;
+                return null;
+            }
+        }).when(mockResponse).addHeader(anyString(), anyString());
+
+        filter.doFilter(mockRequest, mockResponse, mockedFilterChain);
+        Assert.assertTrue(headers[0].equals(""));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/test/java/org/apache/zeppelin/server/CorsFilterTests.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/server/CorsFilterTests.java b/zeppelin-server/src/test/java/org/apache/zeppelin/server/CorsFilterTests.java
deleted file mode 100644
index 3c9152d..0000000
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/server/CorsFilterTests.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * Created by joelz on 8/6/15.
- *
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.zeppelin.server;
-
-import org.apache.zeppelin.socket.TestHttpServletRequest;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.*;
-
-/**
- * BASIC Cors rest api tests
- *
- *
- * @author joelz
- *
- */
-public class CorsFilterTests {
-
-    public static String[] headers = new String[8];
-    public static Integer count = 0;
-
-    @Test
-    public void ValidCorsFilterTest() throws IOException, ServletException {
-        CorsFilter filter = new CorsFilter();
-        HttpServletResponse mockResponse = mock(HttpServletResponse.class);
-        FilterChain mockedFilterChain = mock(FilterChain.class);
-        TestHttpServletRequest mockRequest = mock(TestHttpServletRequest.class);
-        when(mockRequest.getHeader("Origin")).thenReturn("http://localhost:8080");
-        when(mockRequest.getMethod()).thenReturn("Empty");
-        when(mockRequest.getServerName()).thenReturn("localhost");
-
-
-        doAnswer(new Answer() {
-            @Override
-            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
-                headers[count] = invocationOnMock.getArguments()[1].toString();
-                count++;
-                return null;
-            }
-        }).when(mockResponse).addHeader(anyString(), anyString());
-
-        filter.doFilter(mockRequest, mockResponse, mockedFilterChain);
-        Assert.assertTrue(headers[0].equals("http://localhost:8080"));
-    }
-
-    @Test
-    public void InvalidCorsFilterTest() throws IOException, ServletException {
-        CorsFilter filter = new CorsFilter();
-        HttpServletResponse mockResponse = mock(HttpServletResponse.class);
-        FilterChain mockedFilterChain = mock(FilterChain.class);
-        TestHttpServletRequest mockRequest = mock(TestHttpServletRequest.class);
-        when(mockRequest.getHeader("Origin")).thenReturn("http://evillocalhost:8080");
-        when(mockRequest.getMethod()).thenReturn("Empty");
-        when(mockRequest.getServerName()).thenReturn("evillocalhost");
-
-
-        doAnswer(new Answer() {
-            @Override
-            public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
-                headers[count] = invocationOnMock.getArguments()[1].toString();
-                count++;
-                return null;
-            }
-        }).when(mockResponse).addHeader(anyString(), anyString());
-
-        filter.doFilter(mockRequest, mockResponse, mockedFilterChain);
-        Assert.assertTrue(headers[0].equals(""));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
new file mode 100644
index 0000000..34cd411
--- /dev/null
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
@@ -0,0 +1,52 @@
+/**
+ * Created by joelz on 8/6/15.
+ *
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.zeppelin.socket;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.UnknownHostException;
+
+/**
+ * BASIC Zeppelin rest api tests
+ *
+ *
+ * @author joelz
+ *
+ */
+    public class NotebookServerTest {
+
+    @Test
+    public void CheckOrigin() throws UnknownHostException {
+        NotebookServer server = new NotebookServer();
+         Assert.assertTrue(server.checkOrigin(new TestHttpServletRequest(),
+                 "http://" + java.net.InetAddress.getLocalHost().getHostName() + ":8080"));
+    }
+
+    @Test
+    public void CheckInvalidOrigin(){
+        NotebookServer server = new NotebookServer();
+        Assert.assertFalse(server.checkOrigin(new TestHttpServletRequest(), "http://evillocalhost:8080"));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTests.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTests.java b/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTests.java
deleted file mode 100644
index c262593..0000000
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTests.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Created by joelz on 8/6/15.
- *
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.zeppelin.socket;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.net.UnknownHostException;
-
-/**
- * BASIC Zeppelin rest api tests
- *
- *
- * @author joelz
- *
- */
-    public class NotebookServerTests {
-
-    @Test
-    public void CheckOrigin() throws UnknownHostException {
-        NotebookServer server = new NotebookServer();
-         Assert.assertTrue(server.checkOrigin(new TestHttpServletRequest(),
-                 "http://" + java.net.InetAddress.getLocalHost().getHostName() + ":8080"));
-    }
-
-    @Test
-    public void CheckInvalidOrigin(){
-        NotebookServer server = new NotebookServer();
-        Assert.assertFalse(server.checkOrigin(new TestHttpServletRequest(), "http://evillocalhost:8080"));
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/test/resources/zeppelin-site-star.xml
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/resources/zeppelin-site-star.xml b/zeppelin-server/src/test/resources/zeppelin-site-star.xml
new file mode 100644
index 0000000..8f3f4c1
--- /dev/null
+++ b/zeppelin-server/src/test/resources/zeppelin-site-star.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+
+<configuration>
+
+<property>
+  <name>zeppelin.server.addr</name>
+  <value>0.0.0.0</value>
+  <description>Server address</description>
+</property>
+
+<property>
+  <name>zeppelin.server.port</name>
+  <value>8080</value>
+  <description>Server port.</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.dir</name>
+  <value>notebook</value>
+  <description>path or URI for notebook persist</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen</name>
+  <value></value>
+  <description>id of notebook to be displayed in homescreen. ex) 2A94M5J1Z Empty value displays default home screen</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen.hide</name>
+  <value>false</value>
+  <description>hide homescreen notebook from list when this value set to true</description>
+</property>
+
+
+<!-- If used S3 to storage the notebooks, it is necessary the following folder structure bucketname/username/notebook/ -->
+<!--
+<property>
+  <name>zeppelin.notebook.s3.user</name>
+  <value>user</value>
+  <description>user name for s3 folder structure</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.s3.bucket</name>
+  <value>zeppelin</value>
+  <description>bucket name for notebook storage</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.S3NotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.VFSNotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.dir</name>
+  <value>interpreter</value>
+  <description>Interpreter implementation base directory</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreters</name>
+  <value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter</value>
+  <description>Comma separated interpreter configurations. First interpreter become a default</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.connect.timeout</name>
+  <value>30000</value>
+  <description>Interpreter process connect timeout in msec.</description>
+</property>
+
+
+<property>
+  <name>zeppelin.ssl</name>
+  <value>false</value>
+  <description>Should SSL be used by the servers?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.client.auth</name>
+  <value>false</value>
+  <description>Should client authentication be used for SSL connections?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.path</name>
+  <value>keystore</value>
+  <description>Path to keystore relative to Zeppelin configuration directory</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.type</name>
+  <value>JKS</value>
+  <description>The format of the given keystore (e.g. JKS or PKCS12)</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.password</name>
+  <value>change me</value>
+  <description>Keystore password. Can be obfuscated by the Jetty Password tool</description>
+</property>
+
+<!--
+<property>
+  <name>zeppelin.ssl.key.manager.password</name>
+  <value>change me</value>
+  <description>Key Manager password. Defaults to keystore password. Can be obfuscated.</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.ssl.truststore.path</name>
+  <value>truststore</value>
+  <description>Path to truststore relative to Zeppelin configuration directory. Defaults to the keystore path</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.truststore.type</name>
+  <value>JKS</value>
+  <description>The format of the given truststore (e.g. JKS or PKCS12). Defaults to the same type as the keystore type</description>
+</property>
+
+  <property>
+    <name>zeppelin.server.allowed.origins</name>
+    <value>*</value>
+    <description>Allowed sources for REST and WebSocket requests.</description>
+  </property>
+<!--
+<property>
+  <name>zeppelin.ssl.truststore.password</name>
+  <value>change me</value>
+  <description>Truststore password. Can be obfuscated by the Jetty Password tool. Defaults to the keystore password</description>
+</property>
+-->
+
+</configuration>
+

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-server/src/test/resources/zeppelin-site.xml
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/resources/zeppelin-site.xml b/zeppelin-server/src/test/resources/zeppelin-site.xml
new file mode 100644
index 0000000..ae5cea1
--- /dev/null
+++ b/zeppelin-server/src/test/resources/zeppelin-site.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+
+<configuration>
+
+<property>
+  <name>zeppelin.server.addr</name>
+  <value>0.0.0.0</value>
+  <description>Server address</description>
+</property>
+
+<property>
+  <name>zeppelin.server.port</name>
+  <value>8080</value>
+  <description>Server port.</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.dir</name>
+  <value>notebook</value>
+  <description>path or URI for notebook persist</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen</name>
+  <value></value>
+  <description>id of notebook to be displayed in homescreen. ex) 2A94M5J1Z Empty value displays default home screen</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen.hide</name>
+  <value>false</value>
+  <description>hide homescreen notebook from list when this value set to true</description>
+</property>
+
+
+<!-- If used S3 to storage the notebooks, it is necessary the following folder structure bucketname/username/notebook/ -->
+<!--
+<property>
+  <name>zeppelin.notebook.s3.user</name>
+  <value>user</value>
+  <description>user name for s3 folder structure</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.s3.bucket</name>
+  <value>zeppelin</value>
+  <description>bucket name for notebook storage</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.S3NotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.VFSNotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.dir</name>
+  <value>interpreter</value>
+  <description>Interpreter implementation base directory</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreters</name>
+  <value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter</value>
+  <description>Comma separated interpreter configurations. First interpreter become a default</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.connect.timeout</name>
+  <value>30000</value>
+  <description>Interpreter process connect timeout in msec.</description>
+</property>
+
+
+<property>
+  <name>zeppelin.ssl</name>
+  <value>false</value>
+  <description>Should SSL be used by the servers?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.client.auth</name>
+  <value>false</value>
+  <description>Should client authentication be used for SSL connections?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.path</name>
+  <value>keystore</value>
+  <description>Path to keystore relative to Zeppelin configuration directory</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.type</name>
+  <value>JKS</value>
+  <description>The format of the given keystore (e.g. JKS or PKCS12)</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.password</name>
+  <value>change me</value>
+  <description>Keystore password. Can be obfuscated by the Jetty Password tool</description>
+</property>
+
+<!--
+<property>
+  <name>zeppelin.ssl.key.manager.password</name>
+  <value>change me</value>
+  <description>Key Manager password. Defaults to keystore password. Can be obfuscated.</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.ssl.truststore.path</name>
+  <value>truststore</value>
+  <description>Path to truststore relative to Zeppelin configuration directory. Defaults to the keystore path</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.truststore.type</name>
+  <value>JKS</value>
+  <description>The format of the given truststore (e.g. JKS or PKCS12). Defaults to the same type as the keystore type</description>
+</property>
+
+  <property>
+    <name>zeppelin.server.allowed.origins</name>
+    <value>http://onehost:8080,http://otherhost.com,</value>
+    <description>Allowed sources for REST and WebSocket requests.</description>
+  </property>
+<!--
+<property>
+  <name>zeppelin.ssl.truststore.password</name>
+  <value>change me</value>
+  <description>Truststore password. Can be obfuscated by the Jetty Password tool. Defaults to the keystore password</description>
+</property>
+-->
+
+</configuration>
+

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
index 6fda2b2..2fdaee1 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
@@ -18,7 +18,7 @@
 package org.apache.zeppelin.conf;
 
 import java.net.URL;
-import java.util.List;
+import java.util.*;
 
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.XMLConfiguration;
@@ -69,7 +69,7 @@ public class ZeppelinConfiguration extends XMLConfiguration {
 
   /**
    * Load from resource.
-   *
+   *url = ZeppelinConfiguration.class.getResource(ZEPPELIN_SITE_XML);
    * @throws ConfigurationException
    */
   public static ZeppelinConfiguration create() {
@@ -270,9 +270,9 @@ public class ZeppelinConfiguration extends XMLConfiguration {
 
   public String getKeyStorePath() {
     return getRelativeDir(
-        String.format("%s/%s",
-            getConfDir(),
-            getString(ConfVars.ZEPPELIN_SSL_KEYSTORE_PATH)));
+            String.format("%s/%s",
+                    getConfDir(),
+                    getString(ConfVars.ZEPPELIN_SSL_KEYSTORE_PATH)));
   }
 
   public String getKeyStoreType() {
@@ -348,17 +348,30 @@ public class ZeppelinConfiguration extends XMLConfiguration {
   }
 
   public String getRelativeDir(String path) {
-    if (path != null && path.startsWith("/")) {
+    if (path != null && path.startsWith("/") || isWindowsPath(path)) {
       return path;
     } else {
       return getString(ConfVars.ZEPPELIN_HOME) + "/" + path;
     }
   }
 
+  public boolean isWindowsPath(String path){
+    return path.matches("^[A-Za-z]:\\\\.*");
+  }
+
   public String getConfDir() {
     return getString(ConfVars.ZEPPELIN_CONF_DIR);
   }
 
+  public List<String> getAllowedOrigins()
+  {
+    if (getString(ConfVars.ZEPPELIN_ALLOWED_ORIGINS).isEmpty()) {
+      return Arrays.asList(new String[0]);
+    }
+
+    return Arrays.asList(getString(ConfVars.ZEPPELIN_ALLOWED_ORIGINS).toLowerCase().split(","));
+  }
+
 
   /**
    * Wrapper class.
@@ -411,7 +424,10 @@ public class ZeppelinConfiguration extends XMLConfiguration {
     ZEPPELIN_INTERPRETER_REMOTE_RUNNER("zeppelin.interpreter.remoterunner", "bin/interpreter.sh"),
     // Decide when new note is created, interpreter settings will be binded automatically or not.
     ZEPPELIN_NOTEBOOK_AUTO_INTERPRETER_BINDING("zeppelin.notebook.autoInterpreterBinding", true),
-    ZEPPELIN_CONF_DIR("zeppelin.conf.dir", "conf");
+    ZEPPELIN_CONF_DIR("zeppelin.conf.dir", "conf"),
+    // Allows a way to specify a ',' separated list of allowed origins for rest and websockets
+    // i.e. http://localhost:8080
+    ZEPPELIN_ALLOWED_ORIGINS("zeppelin.server.allowed.origins", "*");
 
     private String varName;
     @SuppressWarnings("rawtypes")

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-zengine/src/test/java/org/apache/zeppelin/conf/ZeppelinConfigurationTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/conf/ZeppelinConfigurationTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/conf/ZeppelinConfigurationTest.java
new file mode 100644
index 0000000..dc13eb0
--- /dev/null
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/conf/ZeppelinConfigurationTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.zeppelin.conf;
+
+import junit.framework.Assert;
+import org.apache.commons.configuration.ConfigurationException;
+import org.junit.Test;
+
+import java.net.MalformedURLException;
+import java.util.List;
+
+
+/**
+ * Created by joelz on 8/19/15.
+ */
+public class ZeppelinConfigurationTest {
+    @Test
+    public void getAllowedOrigins2Test() throws MalformedURLException, ConfigurationException {
+
+        ZeppelinConfiguration conf  = new ZeppelinConfiguration(this.getClass().getResource("/test-zeppelin-site2.xml"));
+        List<String> origins = conf.getAllowedOrigins();
+        Assert.assertEquals(2, origins.size());
+        Assert.assertEquals("http://onehost:8080", origins.get(0));
+        Assert.assertEquals("http://otherhost.com", origins.get(1));
+    }
+
+    @Test
+    public void getAllowedOrigins1Test() throws MalformedURLException, ConfigurationException {
+
+        ZeppelinConfiguration conf  = new ZeppelinConfiguration(this.getClass().getResource("/test-zeppelin-site1.xml"));
+        List<String> origins = conf.getAllowedOrigins();
+        Assert.assertEquals(1, origins.size());
+        Assert.assertEquals("http://onehost:8080", origins.get(0));
+    }
+
+    @Test
+    public void getAllowedOriginsNoneTest() throws MalformedURLException, ConfigurationException {
+
+        ZeppelinConfiguration conf  = new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml"));
+        List<String> origins = conf.getAllowedOrigins();
+        Assert.assertEquals(1, origins.size());
+    }
+
+    @Test
+    public void isWindowsPathTestTrue() throws ConfigurationException {
+
+        ZeppelinConfiguration conf  = new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml"));
+        Boolean isIt = conf.isWindowsPath("c:\\test\\file.txt");
+        Assert.assertTrue(isIt);
+    }
+
+    @Test
+    public void isWindowsPathTestFalse() throws ConfigurationException {
+
+        ZeppelinConfiguration conf  = new ZeppelinConfiguration(this.getClass().getResource("/zeppelin-site.xml"));
+        Boolean isIt = conf.isWindowsPath("~/test/file.xml");
+        Assert.assertFalse(isIt);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-zengine/src/test/resources/test-zeppelin-site1.xml
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/resources/test-zeppelin-site1.xml b/zeppelin-zengine/src/test/resources/test-zeppelin-site1.xml
new file mode 100644
index 0000000..cf83b54
--- /dev/null
+++ b/zeppelin-zengine/src/test/resources/test-zeppelin-site1.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+
+<configuration>
+
+<property>
+  <name>zeppelin.server.addr</name>
+  <value>0.0.0.0</value>
+  <description>Server address</description>
+</property>
+
+<property>
+  <name>zeppelin.server.port</name>
+  <value>8080</value>
+  <description>Server port.</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.dir</name>
+  <value>notebook</value>
+  <description>path or URI for notebook persist</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen</name>
+  <value></value>
+  <description>id of notebook to be displayed in homescreen. ex) 2A94M5J1Z Empty value displays default home screen</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen.hide</name>
+  <value>false</value>
+  <description>hide homescreen notebook from list when this value set to true</description>
+</property>
+
+
+<!-- If used S3 to storage the notebooks, it is necessary the following folder structure bucketname/username/notebook/ -->
+<!--
+<property>
+  <name>zeppelin.notebook.s3.user</name>
+  <value>user</value>
+  <description>user name for s3 folder structure</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.s3.bucket</name>
+  <value>zeppelin</value>
+  <description>bucket name for notebook storage</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.S3NotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.VFSNotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.dir</name>
+  <value>interpreter</value>
+  <description>Interpreter implementation base directory</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreters</name>
+  <value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter</value>
+  <description>Comma separated interpreter configurations. First interpreter become a default</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.connect.timeout</name>
+  <value>30000</value>
+  <description>Interpreter process connect timeout in msec.</description>
+</property>
+
+
+<property>
+  <name>zeppelin.ssl</name>
+  <value>false</value>
+  <description>Should SSL be used by the servers?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.client.auth</name>
+  <value>false</value>
+  <description>Should client authentication be used for SSL connections?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.path</name>
+  <value>keystore</value>
+  <description>Path to keystore relative to Zeppelin configuration directory</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.type</name>
+  <value>JKS</value>
+  <description>The format of the given keystore (e.g. JKS or PKCS12)</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.password</name>
+  <value>change me</value>
+  <description>Keystore password. Can be obfuscated by the Jetty Password tool</description>
+</property>
+
+<!--
+<property>
+  <name>zeppelin.ssl.key.manager.password</name>
+  <value>change me</value>
+  <description>Key Manager password. Defaults to keystore password. Can be obfuscated.</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.ssl.truststore.path</name>
+  <value>truststore</value>
+  <description>Path to truststore relative to Zeppelin configuration directory. Defaults to the keystore path</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.truststore.type</name>
+  <value>JKS</value>
+  <description>The format of the given truststore (e.g. JKS or PKCS12). Defaults to the same type as the keystore type</description>
+</property>
+
+  <property>
+    <name>zeppelin.server.allowed.origins</name>
+    <value>http://onehost:8080</value>
+    <description>Allowed sources for REST and WebSocket requests.</description>
+  </property>
+<!--
+<property>
+  <name>zeppelin.ssl.truststore.password</name>
+  <value>change me</value>
+  <description>Truststore password. Can be obfuscated by the Jetty Password tool. Defaults to the keystore password</description>
+</property>
+-->
+
+</configuration>
+

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-zengine/src/test/resources/test-zeppelin-site2.xml
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/resources/test-zeppelin-site2.xml b/zeppelin-zengine/src/test/resources/test-zeppelin-site2.xml
new file mode 100644
index 0000000..ae5cea1
--- /dev/null
+++ b/zeppelin-zengine/src/test/resources/test-zeppelin-site2.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+
+<configuration>
+
+<property>
+  <name>zeppelin.server.addr</name>
+  <value>0.0.0.0</value>
+  <description>Server address</description>
+</property>
+
+<property>
+  <name>zeppelin.server.port</name>
+  <value>8080</value>
+  <description>Server port.</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.dir</name>
+  <value>notebook</value>
+  <description>path or URI for notebook persist</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen</name>
+  <value></value>
+  <description>id of notebook to be displayed in homescreen. ex) 2A94M5J1Z Empty value displays default home screen</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen.hide</name>
+  <value>false</value>
+  <description>hide homescreen notebook from list when this value set to true</description>
+</property>
+
+
+<!-- If used S3 to storage the notebooks, it is necessary the following folder structure bucketname/username/notebook/ -->
+<!--
+<property>
+  <name>zeppelin.notebook.s3.user</name>
+  <value>user</value>
+  <description>user name for s3 folder structure</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.s3.bucket</name>
+  <value>zeppelin</value>
+  <description>bucket name for notebook storage</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.S3NotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.VFSNotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.dir</name>
+  <value>interpreter</value>
+  <description>Interpreter implementation base directory</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreters</name>
+  <value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter</value>
+  <description>Comma separated interpreter configurations. First interpreter become a default</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.connect.timeout</name>
+  <value>30000</value>
+  <description>Interpreter process connect timeout in msec.</description>
+</property>
+
+
+<property>
+  <name>zeppelin.ssl</name>
+  <value>false</value>
+  <description>Should SSL be used by the servers?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.client.auth</name>
+  <value>false</value>
+  <description>Should client authentication be used for SSL connections?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.path</name>
+  <value>keystore</value>
+  <description>Path to keystore relative to Zeppelin configuration directory</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.type</name>
+  <value>JKS</value>
+  <description>The format of the given keystore (e.g. JKS or PKCS12)</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.password</name>
+  <value>change me</value>
+  <description>Keystore password. Can be obfuscated by the Jetty Password tool</description>
+</property>
+
+<!--
+<property>
+  <name>zeppelin.ssl.key.manager.password</name>
+  <value>change me</value>
+  <description>Key Manager password. Defaults to keystore password. Can be obfuscated.</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.ssl.truststore.path</name>
+  <value>truststore</value>
+  <description>Path to truststore relative to Zeppelin configuration directory. Defaults to the keystore path</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.truststore.type</name>
+  <value>JKS</value>
+  <description>The format of the given truststore (e.g. JKS or PKCS12). Defaults to the same type as the keystore type</description>
+</property>
+
+  <property>
+    <name>zeppelin.server.allowed.origins</name>
+    <value>http://onehost:8080,http://otherhost.com,</value>
+    <description>Allowed sources for REST and WebSocket requests.</description>
+  </property>
+<!--
+<property>
+  <name>zeppelin.ssl.truststore.password</name>
+  <value>change me</value>
+  <description>Truststore password. Can be obfuscated by the Jetty Password tool. Defaults to the keystore password</description>
+</property>
+-->
+
+</configuration>
+

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/703b47f7/zeppelin-zengine/src/test/resources/zeppelin-site.xml
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/resources/zeppelin-site.xml b/zeppelin-zengine/src/test/resources/zeppelin-site.xml
new file mode 100644
index 0000000..57d1b23
--- /dev/null
+++ b/zeppelin-zengine/src/test/resources/zeppelin-site.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+
+<configuration>
+
+<property>
+  <name>zeppelin.server.addr</name>
+  <value>0.0.0.0</value>
+  <description>Server address</description>
+</property>
+
+<property>
+  <name>zeppelin.server.port</name>
+  <value>8080</value>
+  <description>Server port.</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.dir</name>
+  <value>notebook</value>
+  <description>path or URI for notebook persist</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen</name>
+  <value></value>
+  <description>id of notebook to be displayed in homescreen. ex) 2A94M5J1Z Empty value displays default home screen</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.homescreen.hide</name>
+  <value>false</value>
+  <description>hide homescreen notebook from list when this value set to true</description>
+</property>
+
+
+<!-- If used S3 to storage the notebooks, it is necessary the following folder structure bucketname/username/notebook/ -->
+<!--
+<property>
+  <name>zeppelin.notebook.s3.user</name>
+  <value>user</value>
+  <description>user name for s3 folder structure</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.s3.bucket</name>
+  <value>zeppelin</value>
+  <description>bucket name for notebook storage</description>
+</property>
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.S3NotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.notebook.storage</name>
+  <value>org.apache.zeppelin.notebook.repo.VFSNotebookRepo</value>
+  <description>notebook persistence layer implementation</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.dir</name>
+  <value>interpreter</value>
+  <description>Interpreter implementation base directory</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreters</name>
+  <value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter,org.apache.zeppelin.geode.GeodeOqlInterpreter,org.apache.zeppelin.postgresql.PostgreSqlInterpreter</value>
+  <description>Comma separated interpreter configurations. First interpreter become a default</description>
+</property>
+
+<property>
+  <name>zeppelin.interpreter.connect.timeout</name>
+  <value>30000</value>
+  <description>Interpreter process connect timeout in msec.</description>
+</property>
+
+
+<property>
+  <name>zeppelin.ssl</name>
+  <value>false</value>
+  <description>Should SSL be used by the servers?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.client.auth</name>
+  <value>false</value>
+  <description>Should client authentication be used for SSL connections?</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.path</name>
+  <value>keystore</value>
+  <description>Path to keystore relative to Zeppelin configuration directory</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.type</name>
+  <value>JKS</value>
+  <description>The format of the given keystore (e.g. JKS or PKCS12)</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.keystore.password</name>
+  <value>change me</value>
+  <description>Keystore password. Can be obfuscated by the Jetty Password tool</description>
+</property>
+
+<!--
+<property>
+  <name>zeppelin.ssl.key.manager.password</name>
+  <value>change me</value>
+  <description>Key Manager password. Defaults to keystore password. Can be obfuscated.</description>
+</property>
+-->
+
+<property>
+  <name>zeppelin.ssl.truststore.path</name>
+  <value>truststore</value>
+  <description>Path to truststore relative to Zeppelin configuration directory. Defaults to the keystore path</description>
+</property>
+
+<property>
+  <name>zeppelin.ssl.truststore.type</name>
+  <value>JKS</value>
+  <description>The format of the given truststore (e.g. JKS or PKCS12). Defaults to the same type as the keystore type</description>
+</property>
+
+<!--
+<property>
+  <name>zeppelin.ssl.truststore.password</name>
+  <value>change me</value>
+  <description>Truststore password. Can be obfuscated by the Jetty Password tool. Defaults to the keystore password</description>
+</property>
+-->
+
+</configuration>
+