diff --git a/migrations/versions/a1f23743bddb_.py b/migrations/versions/a1f23743bddb_.py
new file mode 100644
index 0000000000000000000000000000000000000000..85bed956e41332c1318c411799abf4df725fe05e
--- /dev/null
+++ b/migrations/versions/a1f23743bddb_.py
@@ -0,0 +1,28 @@
+"""empty message
+
+Revision ID: a1f23743bddb
+Revises: 0555db125011
+Create Date: 2017-02-28 13:38:25.900461
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = 'a1f23743bddb'
+down_revision = '0555db125011'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.add_column('protocols', sa.Column('public', sa.Boolean(), nullable=True))
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_column('protocols', 'public')
+    # ### end Alembic commands ###
diff --git a/models/database.py b/models/database.py
index 2a6d373df10438c247d046deaca2215654762edd..029b8339c322c6e074c7234954038842a1e34b91 100644
--- a/models/database.py
+++ b/models/database.py
@@ -125,13 +125,14 @@ class Protocol(db.Model):
     participants = db.Column(db.String)
     location = db.Column(db.String)
     done = db.Column(db.Boolean)
+    public = db.Column(db.Boolean)
 
     tops = relationship("TOP", backref=backref("protocol"), cascade="all, delete-orphan", order_by="TOP.number")
     decisions = relationship("Decision", backref=backref("protocol"), cascade="all, delete-orphan", order_by="Decision.id")
     documents = relationship("Document", backref=backref("protocol"), cascade="all, delete-orphan", order_by="Document.is_compiled")
     errors = relationship("Error", backref=backref("protocol"), cascade="all, delete-orphan", order_by="Error.id")
 
-    def __init__(self, protocoltype_id, date, source=None, content_public=None, content_private=None, start_time=None, end_time=None, author=None, participants=None, location=None, done=False):
+    def __init__(self, protocoltype_id, date, source=None, content_public=None, content_private=None, start_time=None, end_time=None, author=None, participants=None, location=None, done=False, public=False):
         self.protocoltype_id = protocoltype_id
         self.date = date
         self.source = source
@@ -143,6 +144,7 @@ class Protocol(db.Model):
         self.participants = participants
         self.location = location
         self.done = done
+        self.public = public
 
     def __repr__(self):
         return "<Protocol(id={}, protocoltype_id={})>".format(
@@ -190,6 +192,18 @@ class Protocol(db.Model):
         if LOCATION_KEY in remarks:
             self.location = remarks[LOCATION_KEY].value.strip()
 
+    def has_public_view_right(self, user):
+        return (
+            (self.public and self.protocoltype.has_public_view_right(user))
+            or self.protocoltype.has_private_view_right(user)
+        )
+
+    def has_private_view_right(self, user):
+        return self.protocoltype.has_private_view_right(user)
+
+    def has_modify_right(self, user):
+        return self.protocoltype.has_modify_right(user)
+
     def is_done(self):
         return self.done
 
diff --git a/server.py b/server.py
index 8036f3b958449caf2866ed45ca4f2d7092234194..ce68e5e7edf2ef47107db00edf898a7d3c347781 100755
--- a/server.py
+++ b/server.py
@@ -104,7 +104,12 @@ def index():
         key=_sort_key
     )
     finished_protocols = sorted(
-        [protocol for protocol in protocols if protocol.done],
+        [
+            protocol for protocol in protocols
+            if protocol.done
+            and (protocol.has_public_view_right(user)
+                or protocol.has_private_view_right(user))
+        ],
         key=_sort_key
     )
     protocol = finished_protocols[0] if len(finished_protocols) > 0 else None
@@ -112,7 +117,7 @@ def index():
     if check_login():
         todos = [
             todo for todo in Todo.query.all()
-            if todo.protocoltype.has_public_view_right(user)
+            if todo.protocoltype.has_private_view_right(user)
             and not todo.is_done()
         ]
     todos_table = TodosTable(todos) if todos is not None else None
@@ -395,7 +400,7 @@ def list_protocols():
             protocol for protocol in protocols
             if (protocol.protocoltype.has_private_view_right(user)
                 and _matches_search(protocol.content_private))
-            or (protocol.protocoltype.has_public_view_right(user)
+            or (protocol.has_public_view_right(user)
                 and _matches_search(protocol.content_public))
         ]
         for protocol in protocols:
@@ -464,12 +469,12 @@ def show_protocol(protocol_id):
     user = current_user()
     protocol = Protocol.query.filter_by(id=protocol_id).first()
     if protocol is None or not protocol.protocoltype.has_public_view_right(user):
-        flash("Invalides Protokoll.", "alert-error")
+        flash("Invalides Protokoll oder fehlende Zugriffsrechte.", "alert-error")
         return redirect(request.args.get("next") or url_for("index"))
     errors_table = ErrorsTable(protocol.errors)
     visible_documents = [
         document for document in protocol.documents
-        if (not document.is_private and document.protocol.protocoltype.has_public_view_right(user))
+        if (not document.is_private and document.protocol.has_public_view_right(user))
         or (document.is_private and document.protocol.protocoltype.has_private_view_right(user))
     ]
     documents_table = DocumentsTable(visible_documents)
@@ -650,6 +655,19 @@ def update_protocol(protocol_id):
         return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id))
     return render_template("protocol-update.html", upload_form=upload_form, edit_form=edit_form, protocol=protocol)
 
+@app.route("/protocol/publish/<int:protocol_id>")
+@login_required
+def publish_protocol(protocol_id):
+    user = current_user()
+    protocol = Protocol.query.filter_by(id=protocol_id).first()
+    if protocol is None or not protocol.protocoltype.has_modify_right(user):
+        flash("Invalides Protokoll oder keine Berechtigung.", "alert-error")
+        return redirect(request.args.get("next") or url_for("index"))
+    protocol.public = True
+    db.session.commit()
+    return redirect(request.args.get("next") or url_for("show_protocol", protocol_id=protocol.id))
+
+
 @app.route("/prococol/send/<int:protocol_id>")
 @login_required
 def send_protocol(protocol_id):
@@ -891,7 +909,7 @@ def list_decisions():
         search_form.search.data = search_term
     decisions = [
         decision for decision in Decision.query.all()
-        if decision.protocol.protocoltype.has_public_view_right(user)
+        if decision.protocol.has_public_view_right(user)
     ]
     if protocoltype_id is not None and protocoltype_id != -1:
         decisions = [
@@ -926,7 +944,7 @@ def download_document(document_id):
     if ((document.is_private
             and not document.protocol.protocoltype.has_private_view_right(user))
         or (not document.is_private
-            and not document.protocol.protocoltype.has_public_view_right(user))):
+            and not document.protocol.has_public_view_right(user))):
         flash("Keine Berechtigung.", "alert-error")
         return redirect(request.args.get("next") or url_for("index"))
     return send_file(document.as_file_like(), cache_timeout=1, as_attachment=True, attachment_filename=document.name)
diff --git a/templates/protocol-show.html b/templates/protocol-show.html
index 8ff11867f3a0ad3db1f1732ffc72fd8ec2002a03..2a11a9ca2155bcc8f87bb6c097a09d0106ef4e57 100644
--- a/templates/protocol-show.html
+++ b/templates/protocol-show.html
@@ -4,41 +4,47 @@
 
 {% set logged_in = check_login() %}
 {% set user = current_user() %}
-{% set has_public_view_right = protocol.protocoltype.has_public_view_right(user) %}
-{% set has_private_view_right = protocol.protocoltype.has_private_view_right(user) %}
-{% set has_modify_right = protocol.protocoltype.has_modify_right(user) %}
+{% set has_public_type_view_right = protocol.protocoltype.has_public_view_right(user) %}
+{% set has_public_view_right = protocol.has_public_view_right(user) %}
+{% set has_private_view_right = protocol.has_private_view_right(user) %}
+{% set has_modify_right = protocol.has_modify_right(user) %}
 
 {% block content %}
 <div class="container">
-    <div class="btn-group">
-        {% if has_modify_right %}
-            {% if config.ETHERPAD_ACTIVE %}
-            <a class="btn {% if protocol.source is none %}btn-primary{% else %}btn-default{% endif %}" href="{{url_for("etherpull_protocol", protocol_id=protocol.id)}}">Aus Etherpad</a>
-            {% endif %}
-            {% if protocol.source is not none %}
-                <a class="btn btn-primary" href="{{url_for("get_protocol_source", protocol_id=protocol.id)}}">Quelltext</a>
-            {% endif %} 
-            <a class="btn {% if protocol.is_done() %}btn-success{% else %}btn-default{% endif %}" href="{{url_for("update_protocol", protocol_id=protocol.id)}}">Editieren</a>
-            {% if not protocol.is_done() %}
-                <a class="btn btn-default" href="{{url_for("get_protocol_template", protocol_id=protocol.id)}}">Vorlage</a>
+    {% if has_modify_right %}
+        <div class="btn-group">
+            {% if has_modify_right %}
                 {% if config.ETHERPAD_ACTIVE %}
-                <a class="btn btn-primary" href="{{url_for("etherpush_protocol", protocol_id=protocol.id)}}">In Etherpad</a>
+                <a class="btn {% if protocol.source is none %}btn-primary{% else %}btn-default{% endif %}" href="{{url_for("etherpull_protocol", protocol_id=protocol.id)}}">Aus Etherpad</a>
                 {% endif %}
-            {% else %}
-                {% if config.MAIL_ACTIVE %}
-                <a class="btn btn-default" href="{{url_for("send_protocol", protocol_id=protocol.id)}}">Mail versenden</a>
+                {% if protocol.source is not none %}
+                    <a class="btn btn-primary" href="{{url_for("get_protocol_source", protocol_id=protocol.id)}}">Quelltext</a>
+                {% endif %} 
+                <a class="btn {% if protocol.is_done() %}btn-success{% else %}btn-default{% endif %}" href="{{url_for("update_protocol", protocol_id=protocol.id)}}">Editieren</a>
+                {% if not protocol.is_done() %}
+                    <a class="btn btn-default" href="{{url_for("get_protocol_template", protocol_id=protocol.id)}}">Vorlage</a>
+                    {% if config.ETHERPAD_ACTIVE %}
+                    <a class="btn btn-primary" href="{{url_for("etherpush_protocol", protocol_id=protocol.id)}}">In Etherpad</a>
+                    {% endif %}
+                {% else %}
+                    {% if config.MAIL_ACTIVE %}
+                        <a class="btn btn-default" href="{{url_for("send_protocol", protocol_id=protocol.id)}}">Mail versenden</a>
+                    {% endif %}
+                    {% if not protocol.public %}
+                        <a class="btn btn-default" href="{{url_for("publish_protocol", protocol_id=protocol.id)}}">Veröffentlichen</a>
+                    {% endif %}
                 {% endif %}
+                {% if config.ETHERPAD_ACTIVE %}
+                <a class="btn btn-default" href="{{protocol.get_etherpad_link()}}" target="_blank">Etherpad</a>
+                {% endif %}
+                <a class="btn btn-default" href="{{url_for("show_type", type_id=protocol.protocoltype.id)}}">Typ</a>
+                {% if protocol.has_compiled_document() %}
+                    <a class="btn btn-success" href="{{url_for("download_document", document_id=protocol.get_compiled_document().id)}}">Download</a>
+                {% endif %}
+                <a class="btn btn-danger" href="{{url_for("delete_protocol", protocol_id=protocol.id)}}" onclick="return confirm('Bist du dir sicher, dass du das Protokoll {{protocol.get_identifier()}} löschen möchtest?');">Löschen</a>
             {% endif %}
-            {% if config.ETHERPAD_ACTIVE %}
-            <a class="btn btn-default" href="{{protocol.get_etherpad_link()}}" target="_blank">Etherpad</a>
-            {% endif %}
-            <a class="btn btn-default" href="{{url_for("show_type", type_id=protocol.protocoltype.id)}}">Typ</a>
-            {% if protocol.has_compiled_document() %}
-                <a class="btn btn-success" href="{{url_for("download_document", document_id=protocol.get_compiled_document().id)}}">Download</a>
-            {% endif %}
-            <a class="btn btn-danger" href="{{url_for("delete_protocol", protocol_id=protocol.id)}}" onclick="return confirm('Bist du dir sicher, dass du das Protokoll {{protocol.get_identifier()}} löschen möchtest?');">Löschen</a>
-        {% endif %}
-    </div>
+        </div>
+    {% endif %}
     <div class="row">
         <div id="left-column" class="col-lg-6">
             {% if protocol.is_done() %}
@@ -69,7 +75,7 @@
             <h3>Tagesordnung{% if has_modify_right and not protocol.has_nonplanned_tops() %} <a href="{{url_for("new_top", protocol_id=protocol.id)}}">Top hinzufügen</a>{% endif %}</h3>
             {% include "protocol-tops-include.html" %}
 
-            {% if protocol.is_done() %}
+            {% if protocol.is_done() and has_public_view_right %}
             <h3>Beschlüsse</h3>
             <ul>
                 {% if protocol.decisions|length > 0 %}
@@ -105,7 +111,7 @@
                     {{render_table(errors_table)}}
                 {% endif %}
             {% endif %}
-            {% if protocol.documents|length > 0 %}
+            {% if protocol.documents|length > 0 and has_public_view_right %}
                 {{render_table(documents_table)}}
             {% else %}
                 {% if has_modify_right %}
diff --git a/templates/protocol-tops-include.html b/templates/protocol-tops-include.html
index c7302ed1d7e5b88b39568d8c662014c17e266c32..ca7dc22d943a61870667af2fde26e1879da06ba2 100644
--- a/templates/protocol-tops-include.html
+++ b/templates/protocol-tops-include.html
@@ -9,7 +9,7 @@
     {% for top in protocol.tops %}
         <li>
             {{top.name}}
-            {% if not protocol.is_done() and has_private_view_right %}
+            {% if not protocol.is_done() and has_public_type_view_right %}
                 ({{top.number}})
             {% endif %}
             {% if not protocol.is_done() and has_modify_right %}
diff --git a/templates/top-new.html b/templates/top-new.html
index 3b604d0fb68d5b041a6aed4b5a911acb4fa820bd..b06524649de2031a10dd6938efc803131b536c1a 100644
--- a/templates/top-new.html
+++ b/templates/top-new.html
@@ -4,9 +4,10 @@
 
 {% set loggedin = check_login() %}
 {% set user = current_user() %}
-{% set has_public_view_right = protocol.protocoltype.has_public_view_right(user) %}
-{% set has_private_view_right = protocol.protocoltype.has_private_view_right(user) %}
-{% set has_modify_right = protocol.protocoltype.has_modify_right(user) %}
+{% set has_public_type_view_right = protocol.has_public_type_view_right(user) %}
+{% set has_public_view_right = protocol.has_public_view_right(user) %}
+{% set has_private_view_right = protocol.has_private_view_right(user) %}
+{% set has_modify_right = protocol.has_modify_right(user) %}
 
 {% block content %}
 <div class="container">
diff --git a/views/forms.py b/views/forms.py
index 91d108f05102181380cc95c9a7d90a66af92f776..0f8bb8791a8b9c137879f2a47a4a298b02961931 100644
--- a/views/forms.py
+++ b/views/forms.py
@@ -106,6 +106,7 @@ class ProtocolForm(FlaskForm):
     author = StringField("Protokollant")
     participants = StringField("Anwesende")
     done = BooleanField("Fertig")
+    public = BooleanField("Veröffentlicht")
 
 class TopForm(FlaskForm):
     name = StringField("TOP", validators=[InputRequired("Du musst den Namen des TOPs angeben.")])